Data structure (e) of the doubly linked list

Doubly linked list

Prior to the discussion of linked storage structure in a node in only a direct successor of the pointer indicates the domain, thus, only the clockwise starting from the back to find a node to other nodes. To find immediate predecessor node, we need to from header starting. in other words, in the single linked list, the execution time NextElem is O (1), and the execution time PriorElem is O (n). to overcome this disadvantage of unidirectional single linked list, it can be used doubly linked list .
node of a doubly linked list has two pointers in fields, one direct successor point, another point immediate predecessor
and similar single list, a doubly linked list table may be circulating, as shown, there are two rings in the list of FIG.
Here Insert Picture Description

package main.com.cs.test;

public class DoublyLinkedList<T> {

    private int size;

    private Node<T> head;//链表的投节点

    private Node<T> tail;//链表的尾节点

    //构建一个null 链表
    public DoublyLinkedList() {
        this.head =this.tail= new Node<>();
    }


    private static class Node<T>{
        Node<T> Precursor;
        T data;
        Node<T> next;
        
        public Node(T data){
            this(data, null, null);
        }

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

        public String toString(){
            return this.data.toString();
        }

        Node(T data, Node<T> front, Node<T> next){
            this.Precursor = front;
            this.data = data;
            this.next = next;

        }


    }
    



    public boolean add(int index, T data) {
        if(index<0||data==null)
            throw new NullPointerException("index < 0 || data == null");

        int j = 0;
        Node<T> front = this.head;
        //查找要插入结点位置的前一个结点
        while (front.next != null && j < index) {
            j++;
            front = front.next;
        }

        //创建需要插入的结点,并让其前继指针指向front,后继指针指向front.next
        Node<T> q = new Node<T>(data, front, front.next);

        //空双链表插入和尾部插入,无需此操作
        if(front.next != null) {
            //更改front.next的前继指针
            front.next.Precursor = q;
        }
        //更改front的后继指针
        front.next = q;

        //在尾部插入时需要注意更新tail指向
        if(front==this.tail){
            this.tail=q;
        }
        return true;
    }



    public void printLinkList() {    //打印链表
        DoublyLinkedList.Node<T> curr = this.head;
        if (isEmpty()) {
            try {
                throw new Exception("linklist is empty");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        while(curr != null){
            System.out.print(curr.data+" ");

            //判断如果 尾节点的 next 指向 头节点 那么就跳出循环
            if (curr.next == head){
                return;
            }
            curr = curr.next;

        }
    }
    public boolean isEmpty(){//判断链表是否为空
        return this.head == null;
    }

    public static void main(String[] args) {
        DoublyLinkedList<Integer> mylist = new DoublyLinkedList<Integer>();//构造一个空链表
        mylist.add(0,5);
        mylist.add(1,3);
        mylist.add(2,7);
        mylist.add(3,6);
        mylist.printLinkList();
    }
}

Published 69 original articles · won praise 6 · views 2501

Guess you like

Origin blog.csdn.net/qq_40539437/article/details/104002574