La ruta de la lista de secuencias y la lista vinculada (3)

1. Lista doblemente enlazada (sin nodo títere)

  • El principio de la lista enlazada individualmente del artículo anterior es casi el mismo, excepto que el dominio ha cambiado a tres;
    Inserte la descripción de la imagen aquí
    1. Clase de nodo
  • Para el nodo principal, no tiene un nodo predecesor, por lo que su campo predecesor (prev) está vacío (nulo);
  • Igual que el nodo de cola, no tiene nodo sucesor, por lo que su campo sucesor (siguiente) está vacío (nulo);
//定义节点类
class Node1{
    
    
    //一个数据域,俩个地址域(引用)
    public int data;
    public Node1 next;//后继,存放下一个节点的地址
    public Node1 prev;//前驱,存放前一个节点的地址

    //构造方法
    public Node1(){
    
    

    }
    public Node1(int data){
    
    
        this.data = data;
    }
}

2. Lista vinculada

//无傀儡节点的双向链表
class DoubleLinkedList{
    
    
    public Node1 head;//双向链表的头
    public Node1 last;//双向链表的尾巴
    }

3. Inserción de la cabeza
Inserte la descripción de la imagen aquí

  • El nodo es el nodo recién insertado, que necesita establecer contacto con los siguientes nodos,
  • Primero, su siguiente campo necesita poner la dirección (999) del siguiente nodo (cabeza), node.next = head;
  • A continuación, coloque la dirección del propio nodo (888) en el dominio predecesor del último nodo (cabecera), cabecera.prev = nodo;
//头插法
    public void addFirst(int data){
    
    
        Node1 node = new Node1(data);
        //1.第一次插入
        if(head == null){
    
    
            head = node;
            last = node;
            return;
        }
        //其他情况
        node.next = head;//先和链表绑定起来
        head.prev = node;
        head = node;//换头,新插入的节点做头
    }

4. Método de inserción de la cola
Inserte la descripción de la imagen aquí

  • el último es el nodo de cola, la dirección actual del nodo insertado se dará al siguiente campo de último, último.siguiente = cur;
  • También proporcione la última dirección al dominio predecesor de cur, cur.prev = last;
  • (El nodo de nodo insertado a continuación es equivalente a cur, estos son solo el nombre de un nodo, por supuesto, también puede llamar a otros nombres)
//尾插法
    public void addLast(int data){
    
    
        Node1 node = new Node1(data);
        //1.先考虑是不是第一次插入
        if (head == null){
    
    
            head = node;
            last = node;
            return;
        }
        //2.其他情况,用一个cur来标记尾巴,进行尾插法
        //Node1 cur = this.head;
        while(last.next !=null){
    
    
            last = last.next;
        }
        node.prev = last;
        last.next = node;
    }

5. Busque el índice de posición de inserción

//找插入位置index
    public Node1 searchIndex(int index){
    
    
        Node1 cur = this.head;//将链表的头节点给到cur节点,这样就可以用cur遍历整个链表
        int count = 0;
        while(count <index){
    
    
            cur = cur.next;
            count++;
        }
        return cur;
    }

6. Insertar en cualquier posición, el primer nodo de datos es el subíndice 0

//任意位置插入,第一个数据节点为0号下标
    public boolean addIndex(int index,int data){
    
    
        //1.一般对于在指定位置插入,要先考虑插入位置是否合理
        //2.然后考虑会不会插入的位置的是不是头或者尾巴
        //3.剩下的其他情况,
        Node1 node = new Node1(data);
        if (index < 0 || index > size()){
    
    
            System.out.println("插入位置不合法!");
            return false;
        }
        if(index == 0){
    
    
            addFirst(data);
            return true;
        }
        if (index == size()){
    
    
            addLast(data);
            return true;
        }
        //其他情况,找插入位置
        Node1 cur = searchIndex(index);
        node.next = cur;
        node.prev = cur.prev;
        cur.prev.next = node;
        cur.prev = node;

        return true;
    }

7. Descubra si la clave de palabra clave está incluida en la lista de enlaces individuales

//查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
    
    
        //1.直接遍历链表,进行比较,找到就true
        Node1 cur = this.head;
        while(cur != null){
    
    
            if (cur.data == key){
    
    
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

8. Elimina la primera aparición del nodo clave.

//删除第一次出现关键字为key的节点
    public void remove(int key){
    
    
        //1.利用contains判断是否存在关键字,不存在直接跳出
        if (!contains(key)){
    
    
            return;
        }
        //2.存在进行遍历,特殊情况,头节点没有前驱
        Node1 cur = this.head;
        while(cur != null){
    
    
            if (cur.data == key){
    
    
                if(head.data == key){
    
    
                    head = head.next;
                    head.prev = null;
                }else{
    
    
                    cur.prev.next = cur.next;
                    if (cur.next != null){
    
    
                        cur.next.prev = cur.prev;
                    }else{
    
    
                        last = last.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }

9. Elimina todos los nodos cuyo valor es clave

//删除所有值为key的节点
    //第一种,遍历俩次
    /*public void removeAllKey(int key){
        //1.遍历一次,确定关键字的个数
        //2.然后调用remove
        Node1 cur = this.head;
        int count = 0
        while(cur != null){
            count++;
            cur = cur.next;
        }
        while(count > 0){
            remove(key);
            count--;
        }
    }*/
    //第二种,只遍历一次
    public void removeAllKey(int key){
    
    
        Node1 cur = this.head;
        while(cur != null){
    
    
            if (cur.data == key){
    
    
                if(head.data == key){
    
    
                    if (head.next == null){
    
    
                        head = null;
                        return;
                    }
                    head = head.next;
                    head.prev = null;
                }else{
    
    
                    cur.prev.next = cur.next;
                    if (cur.next != null){
    
    
                        cur.next.prev = cur.prev;
                    }else{
    
    
                        last = last.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }

10. Obtenga la longitud de la lista enlazada individualmente

//得到单链表的长度
    public int size(){
    
    
        Node1 cur = this.head;
        int count = 0;
        while(cur != null){
    
    
            cur = cur.next;
            count++;
        }
        return count;
    }

11. Imprimir lista doblemente enlazada

//打印双向链表
    public void display(){
    
    
        Node1 cur = this.head;
        while(cur != null){
    
    
            System.out.print(cur.data+" ");
            cur = cur.next;//遍历整个链表
        }
        System.out.println();
    }

12. Limpiar lista doblemente enlazada

//清除双向链表
    public void clear(){
    
    
        head = null;
    }
}
  • Código fuente completo y resultados de ejecución
//定义节点类
class Node1{
    
    
    //一个数据域,俩个地址域(引用)
    public int data;
    public Node1 next;//后继
    public Node1 prev;//前驱

    //构造方法
    public Node1(){
    
    

    }
    public Node1(int data){
    
    
        this.data = data;
    }
}

//无傀儡节点的双向链表
class DoubleLinkedList{
    
    
    public Node1 head;//双向链表的头
    public Node1 last;//双向链表的尾巴

    //头插法
    public void addFirst(int data){
    
    
        Node1 node = new Node1(data);
        //1.第一次插入
        if(head == null){
    
    
            head = node;
            last = node;
            return;
        }
        //其他情况
        node.next = head;//先和链表绑定起来
        head.prev = node;
        head = node;//换头,新插入的节点做头
    }
    //尾插法
    public void addLast(int data){
    
    
        Node1 node = new Node1(data);
        //1.先考虑是不是第一次插入
        if (head == null){
    
    
            head = node;
            last = node;
            return;
        }
        //2.其他情况,用一个cur来标记尾巴,进行尾插法
        //Node1 cur = this.head;
        while(last.next !=null){
    
    
            last = last.next;
        }
        node.prev = last;
        last.next = node;

    }
    //找插入位置index
    public Node1 searchIndex(int index){
    
    
        Node1 cur = this.head;
        int count = 0;
        while(count <index){
    
    
            cur = cur.next;
            count++;
        }
        return cur;
    }
    //任意位置插入,第一个数据节点为0号下标
    public boolean addIndex(int index,int data){
    
    
        //1.一般对于在指定位置插入,要先考虑插入位置是否合理
        //2.然后考虑会不会插入的位置的是不是头或者尾巴
        //3.剩下的其他情况,
        Node1 node = new Node1(data);
        if (index < 0 || index > size()){
    
    
            System.out.println("插入位置不合法!");
            return false;
        }
        if(index == 0){
    
    
            addFirst(data);
            return true;
        }
        if (index == size()){
    
    
            addLast(data);
            return true;
        }
        //其他情况,找插入位置
        Node1 cur = searchIndex(index);
        node.next = cur;
        node.prev = cur.prev;
        cur.prev.next = node;
        cur.prev = node;

        return true;
    }
    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
    
    
        //1.直接遍历链表,进行比较,找到就true
        Node1 cur = this.head;
        while(cur != null){
    
    
            if (cur.data == key){
    
    
                return true;
            }
            cur = cur.next;
        }
        return false;
    }
    //删除第一次出现关键字为key的节点
    public void remove(int key){
    
    
        //1.利用contains判断是否存在关键字,不存在直接跳出
        if (!contains(key)){
    
    
            return;
        }
        //2.存在进行遍历,特殊情况,头节点没有前驱
        Node1 cur = this.head;
        while(cur != null){
    
    
            if (cur.data == key){
    
    
                if(head.data == key){
    
    
                    head = head.next;
                    head.prev = null;
                }else{
    
    
                    cur.prev.next = cur.next;
                    if (cur.next != null){
    
    
                        cur.next.prev = cur.prev;
                    }else{
    
    
                        last = last.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }
    //删除所有值为key的节点
    //第一种,遍历俩次
    /*public void removeAllKey(int key){
        //1.遍历一次,确定关键字的个数
        //2.然后调用remove
        Node1 cur = this.head;
        int count = 0
        while(cur != null){
            count++;
            cur = cur.next;
        }
        while(count > 0){
            remove(key);
            count--;
        }
    }*/
    //第二种,只遍历一次
    public void removeAllKey(int key){
    
    
        Node1 cur = this.head;
        while(cur != null){
    
    
            if (cur.data == key){
    
    
                if(head.data == key){
    
    
                    if (head.next == null){
    
    
                        head = null;
                        return;
                    }
                    head = head.next;
                    head.prev = null;
                }else{
    
    
                    cur.prev.next = cur.next;
                    if (cur.next != null){
    
    
                        cur.next.prev = cur.prev;
                    }else{
    
    
                        last = last.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }
    //得到单链表的长度
    public int size(){
    
    
        Node1 cur = this.head;
        int count = 0;
        while(cur != null){
    
    
            cur = cur.next;
            count++;
        }
        return count;
    }
    //打印双向链表
    public void display(){
    
    
        Node1 cur = this.head;
        while(cur != null){
    
    
            System.out.print(cur.data+" ");
            cur = cur.next;//遍历整个链表
        }
        System.out.println();
    }
    //清除双向链表
    public void clear(){
    
    
        head = null;
    }
}

  • Clase de prueba
public class TestDemo2 {
    
    
    public static void main(String[] args) {
    
    
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        doubleLinkedList.addFirst(1);
        doubleLinkedList.addFirst(1);
        doubleLinkedList.addFirst(2);
        doubleLinkedList.addFirst(3);
        doubleLinkedList.addFirst(1);
        doubleLinkedList.display();
        doubleLinkedList.addLast(4);
        doubleLinkedList.addLast(5);
        doubleLinkedList.addFirst(1);
        doubleLinkedList.addLast(6);
        doubleLinkedList.addFirst(1);
        doubleLinkedList.addFirst(99);
        doubleLinkedList.addFirst(1);
        doubleLinkedList.addLast(6);
        doubleLinkedList.display();
        /*doubleLinkedList.remove(1);
        doubleLinkedList.display();*/
        doubleLinkedList.removeAllKey(1);
        doubleLinkedList.display();

    }
}

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_45665172/article/details/109566855
Recomendado
Clasificación