Java数据结构之链表相关知识总结

作者:weixin_42280618 时间:2023-11-02 00:29:28 

一、链表

1.1 概述

链表是真正动态的数据结构,最简单的动态数据结构,基本用于辅助组成其他数据结构。

数据存储在“节点”(Node)中

Java数据结构之链表相关知识总结

优点:真正的动态,不需要处理固定容量的问题
缺点:丧失了随机访问的能力

1.2 链表使用的基本功能

定义Node节点


private class Node{
       public E e;
       public Node next;

public Node(E e, Node next){
           this.e = e;
           this.next = next;
       }

public Node(E e){
           this(e, null);
       }

public Node(){
           this(null,null);
       }

@Override
       public String toString() {
           return e.toString();
       }
   }

向链表中添加元素

Java数据结构之链表相关知识总结

具体代码实现:


//向链表中间添加元素
   //在链表的index(0-based)位置添加新的元素e
   public void add(int index, E e){
       if(index < 0 || index > size)
           throw new IllegalArgumentException("Add failed.Illeagl failed.");
       Node prev = dummyHead;
       for (int i = 0; i < index; i++) {
           prev = prev.next;
       }
//            Node node = new Node(e);
//            node.next = prev.next;
//            prev.next = node;

prev.next = new Node(e, prev.next);
       size++;
   }

向链表中删除元素

Java数据结构之链表相关知识总结

具体代码实现:


//链表中删除index(0-based)位置的元素,返回删除的元素
   public E remove(int index){
       if(index < 0 || index >= size)
           throw new IllegalArgumentException("Remove failed.Illeagl failed.");
       Node pre = dummyHead;
       for (int i = 0; i < index; i++) {
           pre = pre.next;
       }
       Node retNode = pre.next;
       pre.next = retNode.next;
       retNode.next = null;
       size--;

return retNode.e;
   }

链表功能的实现及测试类


public class LinkedList<E> {
   private class Node{
       public E e;
       public Node next;

public Node(E e, Node next){
           this.e = e;
           this.next = next;
       }

public Node(E e){
           this(e, null);
       }

public Node(){
           this(null,null);
       }

@Override
       public String toString() {
           return e.toString();
       }
   }

private Node dummyHead;
   private int size;

public LinkedList(){
       dummyHead = new Node(null, null);
       size = 0;
   }

//获取链表中的元素个数
   public int getSize(){
       return size;
   }

//返回链表是否为空
   public boolean isEmpty(){
       return size == 0;
   }

//向链表头添加元素
   public void addFirst(E e){
//        Node node = new Node(e);
//        node.next = head;
//        head = node;

add(0, e);
   }

//向链表中间添加元素
   //在链表的index(0-based)位置添加新的元素e
   public void add(int index, E e){
       if(index < 0 || index > size)
           throw new IllegalArgumentException("Add failed.Illeagl failed.");
       Node prev = dummyHead;
       for (int i = 0; i < index; i++) {
           prev = prev.next;
       }
//            Node node = new Node(e);
//            node.next = prev.next;
//            prev.next = node;

prev.next = new Node(e, prev.next);
       size++;
   }

//在链表的末尾添加新的元素e
   public void addLast(E e){
       add(size, e);
   }

//获得链表的第index(0-based)个位置的元素
   //在链表中不是一个常用的操作
   public E get(int index){
       if(index < 0 || index > size)
           throw new IllegalArgumentException("Add failed.Illeagl failed.");
       Node cur = dummyHead.next;
       for (int i = 0; i < index; i++) {
           cur = cur.next;
       }
       return cur.e;
   }

//获得链表的第一个元素
   public E getFirst(){
       return get(0);
   }

//获得链表的最后一个元素
   public E getLast(){
       return get(size - 1);
   }

//修改链表的第index(0-based)个位置的元素
   //在链表中不是一个常用的操作
   public void set(int index, E e){
       if(index < 0 || index > size)
           throw new IllegalArgumentException("Add failed.Illeagl failed.");
       Node cur = dummyHead.next;
       for (int i = 0; i < index; i++) {
           cur = cur.next;
       }
       cur.e = e;
   }

//查找链表中是否有元素e
   public boolean contains(E e){
       Node cur = dummyHead.next;
       while(cur != null){
           if(cur.e.equals(e)){
               return true;
           }
           cur = cur.next;
       }
       return false;
   }

//链表中删除index(0-based)位置的元素,返回删除的元素
   public E remove(int index){
       if(index < 0 || index >= size)
           throw new IllegalArgumentException("Remove failed.Illeagl failed.");
       Node pre = dummyHead;
       for (int i = 0; i < index; i++) {
           pre = pre.next;
       }
       Node retNode = pre.next;
       pre.next = retNode.next;
       retNode.next = null;
       size--;

return retNode.e;
   }

//从链表中删除第一个元素
   public E removeFirst(){
       return remove(0);
   }

//从链表中删除最后一个元素
   public E removeLast(){
       return remove(size - 1);
   }
   @Override
   public String toString() {
       StringBuilder res = new StringBuilder();

//        Node cur = dummyHead.next;
//        while (cur != null){
//            res.append(cur + "->");
//            cur = cur.next;
//        }

for (Node cur = dummyHead.next; cur != null; cur = cur.next){
           res.append(cur + "->");
       }
       res.append("null");
       return res.toString();
   }
   public static void main(String[] args) {
       LinkedList<Integer> linkedList = new LinkedList<>();
       for (int i = 0; i < 5; i++) {
           linkedList.addFirst(i);
           System.out.println(linkedList);
       }

linkedList.add(2, 666);
       System.out.println(linkedList);

linkedList.remove(2);
       System.out.println(linkedList);

linkedList.removeFirst();
       System.out.println(linkedList);

linkedList.removeLast();
       System.out.println(linkedList);
   }
}

二、链表实现栈操作

使用第二章中的栈接口,创建第一节中的链表实现对象,实现栈的操作,具体如下:


public class LinkedListStack<E> implements Stack<E> {
   private LinkedList<E> list;
   public LinkedListStack(){
       list = new LinkedList<>();
   }

@Override
   public int getSize() {
       return list.getSize();
   }

@Override
   public boolean isEmpty() {
       return list.isEmpty();
   }

@Override
   public void push(E value) {
       list.addFirst(value);
   }

@Override
   public E pop() {
       return list.removeFirst();
   }

@Override
   public E peek() {
       return list.getFirst();
   }

@Override
   public String toString() {
       StringBuilder res = new StringBuilder();
       res.append("Stack : top");
       res.append(list);
       return res.toString();
   }

public static void main(String[] args) {
       LinkedListStack<Integer> stack = new LinkedListStack<>();
       for (int i = 0; i < 5; i++) {
           stack.push(i);
           System.out.println(stack);
       }

stack.pop();
       System.out.println(stack);
   }
}

三、链表实现队列操作

使用第二章中的队列接口,创建无头节点的链表实现队列操作,具体如下:


public class LinkedListQueue<E> implements Queue<E> {
   private class Node{
       public E e;
       public LinkedListQueue.Node next;

public Node(E e, LinkedListQueue.Node next){
           this.e = e;
           this.next = next;
       }

public Node(E e){
           this(e, null);
       }

public Node(){
           this(null,null);
       }

@Override
       public String toString() {
           return e.toString();
       }
   }

private Node head,tail;
   private int size;
   public LinkedListQueue(){
       head = null;
       tail = null;
       size = 0;
   }

@Override
   public int getSize() {
       return size;
   }

@Override
   public boolean isEmpty() {
       return size == 0;
   }

@Override
   public void enqueue(E e) {
       if(tail == null){
           tail = new Node(e);
           head = tail;
       }else{
           tail.next = new Node(e);
           tail = tail.next;
       }
       size++;
   }

@Override
   public E dequeue() {
       if (isEmpty())
           throw new IllegalArgumentException("Cannot dequeue form any empty queue.");
       Node retNode = head;
       head = head.next;
       retNode.next = null;
       if (head == null)
           tail = null;
       return retNode.e;
   }

@Override
   public E getFront() {
       if (isEmpty())
           throw new IllegalArgumentException("Cannot getFront form any empty queue.");
       return head.e;
   }

@Override
   public String toString() {
       StringBuilder res = new StringBuilder();
       res.append("Queue : front ");

Node cur = head;
       while (cur != null){
           res.append(cur + "->");
           cur = cur.next;
       }

res.append("Null tail");
       return res.toString();
   }

public static void main(String[] args) {
       LinkedListQueue<Integer> queue = new LinkedListQueue<>();
       for (int i = 0; i < 10; i++) {
           queue.enqueue(i);
           System.out.println(queue);

if(i % 3 == 2){
               queue.dequeue();
               System.out.println(queue);
           }
       }

}
}

来源:https://blog.csdn.net/weixin_42280618/article/details/117917438

标签:Java,链表
0
投稿

猜你喜欢

  • Android实现Flip翻转动画效果

    2022-05-11 20:08:57
  • java9版本特性资源自动关闭的语法增强

    2023-10-30 23:35:24
  • .NET垃圾回收器(GC)原理浅析

    2023-11-24 13:50:56
  • Unity 如何通过反射给gameObject添加组件

    2022-06-14 20:58:34
  • Android 监听手机GPS打开状态实现代码

    2022-09-28 08:56:38
  • java实现http的Post、Get、代理访问请求

    2021-10-30 08:13:47
  • java使用IO流对数组排序实例讲解

    2023-09-04 02:24:19
  • Android解析XML文件升级APK的方法

    2022-06-05 20:47:26
  • C#中字符串的一般性和特殊性

    2023-03-23 19:06:07
  • 实例详解SpringBoot默认的JSON解析方案

    2023-07-21 07:34:20
  • Android Studio 3.0中mipmap-anydpi-v26是什么东东

    2023-10-11 01:17:44
  • Springboot多种情况yml配置代码实例

    2022-05-14 23:26:00
  • JAVA读取文件夹大小的几种方法实例

    2021-05-24 21:01:53
  • Android仿支付宝支付密码输入框

    2021-12-31 00:30:31
  • SpringBoot集成支付宝沙箱支付的实现示例

    2023-10-31 19:22:20
  • java元注解@Inherited的使用详解

    2023-09-15 04:58:48
  • Android中的SQL查询语句LIKE绑定参数问题解决办法(sqlite数据库)

    2023-09-12 14:04:06
  • SpringBoot整合Web开发之文件上传与@ControllerAdvice

    2021-09-29 04:43:55
  • 完美解决Android三星手机从图库选择照片旋转问题

    2023-10-11 00:32:53
  • Java优先队列(PriorityQueue)重写compare操作

    2022-10-02 03:59:12
  • asp之家 软件编程 m.aspxhome.com