数据结构之链表

参考博文:
Java数据结构和算法(七)——链表

一、链表定义

是一种链式存储结构, 数据在物理空间是分散存储的. 每个节点包含2部分, 存储的数据和指向下一个节点的地址.

二、链表的种类

1.单链表

在这里插入图片描述
单链表特点
1.只能向一个方向遍历
2.添加元素从头部插入, 若想向尾部插入元素, 必须遍历前n-1个节点

通过单向链表可实现栈, 添加节点删除头节点对应栈的入栈出栈

新增节点

在这里插入图片描述

删除节点

在这里插入图片描述
实现思路: 将当前节点的上一个节点指向当前节点的下一个节点

代码实现

public class SinglyLinkedList {
    // 指向头结点
    private Node head; 
    // 链表长度
    private int size;

    public SinglyLinkedList() {
        this.size = 0;
        this.head = null;
    }

// 定义一个内部类Node
private class Node {
     private Object data;
     private Node next;

     public Node(Object data, Node next) {
         this.data = data;
         this.next = next;
     }
 }

 // 增加节点
	 public void addNode(Object obj) {
      if (size == 0) {
          Node newNode = new Node(obj, null);
          head = newNode;
          size++;
          return;
      }

	  Node previous = head;
      Node newNode = new Node(obj, previous );
      head = newNode; // 将头部地址指向当前节点
      size++;
    }
 
 // 打印链表
    public void display() {
        if (size == 0) {
            System.out.println("[]");
        } else {
            Node current = head;
            // 遍历前n-1个节点
            while (current.next != null) {
                Object data = current.data;
                System.out.print(data + "==>");
                current = current.next;
            }
            System.out.println(current.data);// 打印最后一个
        }
    }
    
	// 删除头节点
	public Object deleteHeadNode() {
	        if (size != 0) {
	            Object obj = head.data;
	            head = head.next;
	            size--;
	            return obj;
	        }
	        return null;
	    }

   // 查找链表中的元素
    public Object find(Object obj) {
        if (size == 0) {
            return null;
        }

        Node current = head;
        while (current.next != null) {
            if (current.data.equals(obj)) {
                return obj;
            }
            current = current.next;
        }
        
        // 最后一个元素
        if (current.data.equals(obj)) {
            return obj;
        }
        return null;
    }
2.双端链表

双端链表相对于单链表多了一个尾节点的引用, 这样向尾部添加数据就方便多了
在这里插入图片描述
双端链表实现队列, 向尾部插入数据对应入队, 删除头部节点对应出队

public class DoublEendedList {
    
    private Node head; // 指向头部节点
    private Node tail; // 指向尾部节点
    private int size;

    public DoublEendedList() {
        this.head = null;
        this.tail = null;
        this.size = 0;
    }
    // 节点类
    private class Node {
        private Object data;//节点数据
        private Node next;// 节点指向下一节点连接

        public Node(Object data, Node next) {
            this.data = data;
            this.next = next;
        }
    }
}

// 在头部插入节点
    public void addNode(Object data) {
        if (size == 0) {
            Node node = new Node(data, null);
            head = node;
            tail = node;
        } else {
            Node node = new Node(data, head);
            head = node;
        }
        size++;
    }

// 在尾部添加节点
    public Object addTail(Object obj) {
        if (size == 0) {
            Node node = new Node(obj, null);
            head = node;
            tail = node;
        } else {
            Node node = new Node(obj, null);
            tail.next = node;
            tail = node;
        }
        size++;
        return tail.data;
    }

   // 从后往前遍历
    public void displayBackword() {
        Node last = tail;

        if (size == 0) {
            System.out.println("[]");
        } else {
            while (last.previous != null) { // 遍历后n-1个
                System.out.print(last.data + "=>");
                last = last.previous;
            }
            System.out.println(last.data);// 遍历至第一个
        }
    }

    // 从前往后遍历
    public void displayForword() {

        Node current = head;

        if (size == 0) {
            System.out.println("[]");
        } else {
            while (current.next != null) {
                System.out.print(current.data + "==>");
                current = current.next;
            }
            System.out.println(current.data);// 遍历至最后一个
        }
    }

// 删除头部节点
    public Object deleteHead() {
        Object obj = null;

        if (size == 0) {
            return null;
        }

        if (size == 1) {
            obj = head.data;
            head = null;
            size--;
        } else {
            obj = head.data;
            Node next = head.next;
            head = next;
            size--;
        }
        return obj;
    }

// 遍历链表
public void display() {
    if (size == 0) {
        System.out.println("[]");
    } else {
        Node current = head;
        while (current.next != null) {
            Object data = current.data;
            System.out.print(data + "==>");
            current = current.next;
        }
        System.out.println(current.data);// 打印最后一个
    }

 // 删除节点
    public Object deletNode(Object obj) {

        Object item = null;

        if (size == 0) {
            return item;
        }

        if (size == 1) {
            if (head.data.equals(obj)) {
                head = null;
                tail = null;
                size--;
                item = obj;
            }
        } else {
            Node current = head;
            while (current.next != null) {
                if (current.previous == null) {// 如果是第一个
                    if (head.data.equals(obj)) {
                        head = current.next;
                        head.previous = null;
                        current = head;
                        size--;
                        item = obj;
                        continue;
                    }
                    current = current.next;
                } else {
                    if (current.data.equals(obj)) {
                        Node previous = current.previous;
                        Node next = current.next;

                        previous.next = next;
                        next.previous = previous;
                        current = current.next;

                        size--;
                        item = obj;
                        continue;
                    }
                    current = current.next;
                }
            }
            if (current.data.equals(obj)) { // 处理最后一个节点
                current.previous.next = null;
                tail = current.previous;
                size--;
                item = obj;
            }
        }
        return item;
    }
}
3.双向链表

双向链表相对于双端链表, 节点的结构新增加了指向前一个节点的地址, 这样链表就可以双向遍历了.
在这里插入图片描述
新增节点:
在这里插入图片描述

public class TwoWayLinkedList {

    private Node head;
    private Node tail;
    private int size;

    public TwoWayLinkedList() {
        size = 0;
        head = null;
        tail = null;
    }

 	private class Node {
        private Object data;
        private Node next;
        private Node previous;

        public Node(Object data, Node next, Node previous) {
            this.data = data;
            this.next = next;
            this.previous = previous;
        }
    }

 	// 向头部插入节点
    public Object addNode(Object obj) {
        if (size == 0) {
            Node node = new Node(obj, null, null);
            head = node;
            tail = node;
        } else {
            Node node = new Node(obj, head, null);
            head.previous = node;
            head = node;
        }
        size++;
        return obj;
    }
	
	// 向尾部插入节点
    public Object addTailNode(Object obj) {
        if (size == 0) {
            Node node = new Node(obj, null, null);
            head = node;
            tail = node;
        } else {
            Node node = new Node(obj, null, tail);
            tail.next = node;
            tail = node;
        }
        size++;
        return obj;
    }
	
	// 查找节点
    public Object find(Object obj) {
        Node current = head;

        if (size == 0) {
            return null;
        } else {
            while (current.next != null) {
                if (current.data.equals(obj)) {
                    return obj;
                }
                current = current.next;
            }
            if (current.data.equals(obj)) {
                return obj;
            }
        }
        return null;
    }
}

// 删除头部节点
    public Object deleteHeadNode() {

        Node current = head;

        if (size == 0) {
            return current;
        } else {
            head = current.next;
            head.previous = null;
        }
        size--;
        return current.data;
    }

   // 删除尾部节点
    public Object deleteTailNode() {

        Node last = tail;

        if (size == 0) {
            return last;
        } else {
            if (last.previous != null) {
                tail = last.previous;
                tail.next = null;
                size--;
            } else {
                // 只有一个节点
                head = null;
                tail = null;
                size--;
            }
        }
        return last.data;
    }

   // 删除节点
    public Object deletNode(Object obj) {

        Object item = null;

        if (size == 0) {
            return item;
        }

       if (size == 1) {
            if (head.data.equals(obj)) {
                head = null;
                tail = null;
                size--;
                item = obj;
            }
        } else {
            Node current = head;
            while (current.next != null) {
                if (current.previous == null) {// 如果是第一个
                    if (head.data.equals(obj)) {
                        head = current.next;
                        head.previous = null;
                        current = head;
                        size--;
                        item = obj;
                        continue;
                    }
                    current = current.next;
                } else {
                    if (current.data.equals(obj)) {
                        Node previous = current.previous;
                        Node next = current.next;

                        previous.next = next;
                        next.previous = previous;
                        current = current.next;

                        size--;
                        item = obj;
                        continue;
                    }
                    current = current.next;
                }
            }
            if (current.data.equals(obj)) { // 处理最后一个节点
                current.previous.next = null;
                tail = current.previous;
                size--;
                item = obj;
            }
        }
        return item;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值