Lista enlazada, lista enlazada circular bidireccional unidireccional, punteros transversales, rápidos y lentos (de entrada a entrada)

Lista enlazada, lista enlazada circular bidireccional unidireccional, punteros transversales, rápidos y lentos (de entrada a entrada)

¿Qué es una lista enlazada?

Una lista enlazada es una estructura de datos básica, aunque no es tan conveniente como una matriz para obtener valores, es mucho más conveniente que una matriz para expandir y eliminar. La unidad básica de una lista enlazada es un nodo. La dirección del siguiente nodo también se puede almacenar en el nodo mientras se almacenan los datos. Por lo tanto, al eliminar o crear un nuevo nodo, es mucho más eficiente que una matriz.

Clasificación de listas enlazadas

Lista enlazada unidireccional:
si el siguiente nodo del último nodo apunta a nulo, es una lista enlazada unidireccional .
Si el siguiente nodo del último nodo apunta al nodo principal, es una lista circular unidireccional .
lista enlazada simple
lista enlazada circular unidireccional

//单向链表的节点
public class Link {
    
    
    int value; //可以存储数据
    Link next; //下一个节点的地址
    
    public Link() {
    
    }
    public Link(int value) {
    
     this.value = value; }
}

link1 = new Link();
link2 = new Link();
link3 = new Link();
//单向链表
link1.next = link2;
link2.next = link3;
link3.next = null;
//单向循环列表
link1.next = link2;
link2.next = link3;
link3.next = link1

Lista doblemente enlazada:
si dos nodos adyacentes apuntan entre sí y el siguiente nodo del último nodo apunta a nulo, es una lista doblemente enlazada .
Si hay puntos mutuos entre dos nodos adyacentes, y el siguiente nodo del último nodo apunta al nodo principal, es una lista circular bidireccional .
Lista doblemente enlazada
lista doblemente enlazada

//双向链表的节点
public class Link {
    
    
    int value; //可以存储数据
    Link next; //下一个节点的地址
    Link last; //上一个节点的地址
    
    public Link() {
    
    }
    public Link(int value) {
    
     this.value = value; }
}

link1 = new Link();
link2 = new Link();
link3 = new Link();
//双向链表
link1.next = link2;
link1.last = null;
link2.next = link3;
link2.last = link1;
link3.next = null;
link3.last = link2;
//双向循环列表
link1.next = link2;
link1.last = link3;
link2.next = link3;
link2.last = link1;
link3.next = link1
link3.last = link2;

Recorrido de lista

El método de recorrido de la lista doblemente enlazada y la lista de enlace simple es el mismo, y la lista doblemente enlazada tiene la dirección del elemento anterior, por lo que la operación real es más conveniente de usar.

    public static void main(String[] args) {
    
    
        Link link1 = new Link();
        Link link2 = new Link();
        Link link3 = new Link();
        link1.next = link2;
        link2.next = link3;
        link3.next = link1;


        Link index = link1;
        while (true){
    
    
            System.out.print(index.value+" "); //输出值
            //判断是否为最后一个
            if (index.next == null){
    
    
                // 链表已经到达最后一位
                System.out.println("非循环链表");
                break;
            }
            index = index.next;
            //判断是否是循环列表
            if (index == link1){
    
    
                System.out.println("循环链表");
                break;
            }
        }
    }
    //这段代码会输出: 0 0 0 循环链表

puntero de velocidad

Los punteros rápido y lento definen dos punteros (no existe el concepto de punteros en java, deberían ser referencias), el puntero rápido avanza dos nodos a la vez y el puntero lento avanza un nodo a la vez, porque el puntero rápido es el doble de la velocidad del puntero lento, por lo que cuando el puntero rápido alcanza el último nodo, el puntero lento solo alcanza el nodo medio de la lista enlazada (debe prestar atención a la paridad del número de nodos). También se puede juzgar si la lista enlazada es una lista enlazada circular utilizando los punteros rápido y lento.
Tome la estructura de lista enlazada unidireccional anterior como ejemplo para determinar si la lista enlazada es una lista enlazada circular:

 public static void main(String[] args) {
    
    
        Link link1 = new Link();
        Link link2 = new Link();
        Link link3 = new Link();
        link1.next = link2;
        link2.next = link3;
        link3.next = link1;

		//定义快慢指针
        Link fast = link1;
        Link slow = link1;
        while (true){
    
    
            if (fast.next==null || fast.next.next==null){
    
    
                /*
                    只要有null就不是循环链表
                    当链表节点个数为奇数,就是(fast.next = null),慢指针正好是中间节点
                    当链表节点数为偶数,(fast.next = null)且(fast.next.next=null)慢指针是中间的两个节点的前一个
                */
                System.out.println("非循环链表");
                break;
            }
            fast = fast.next.next;
            slow = slow.next;
            if (fast.equals(slow)){
    
    
                //当快慢指针重合,就说明这是一个环形链表
                System.out.println("循环链表");
                break;
            }
        }
    }

Los punteros rápidos y lentos se usan mucho en problemas de algoritmos, y su uso razonable en el desarrollo real aumentará en gran medida la eficiencia de ejecución del código.

Supongo que te gusta

Origin blog.csdn.net/qq_39950529/article/details/124356523
Recomendado
Clasificación