Estructura de datos (e) de la lista doblemente enlazada

lista doblemente enlazada

Antes de la discusión de la estructura de almacenamiento vinculado en un nodo sólo en un sucesor directo del puntero indica el dominio, por lo tanto, sólo la agujas del reloj a partir de la parte de atrás para encontrar un nodo a otros nodos. Para encontrar el nodo predecesor inmediato, tenemos que partir cabecera de partida. en otras palabras, en la lista enlazada única, el tiempo de ejecución NextElem es O (1), y el tiempo de ejecución PriorElem es O (n). para superar esta desventaja de lista enlazada única unidireccional, que puede ser utilizado lista doblemente enlazada .
nodo de una lista doblemente enlazada tiene dos punteros en campos, un punto sucesor directo, otro punto predecesor inmediato
y lista única similares, una mesa lista doblemente enlazada puede estar circulando, como se muestra, hay dos anillos en la lista de la figura.
Aquí Insertar imagen Descripción

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();
    }
}

Publicado 69 artículos originales · ganado elogios 6 · vistas 2501

Supongo que te gusta

Origin blog.csdn.net/qq_40539437/article/details/104002574
Recomendado
Clasificación