[Estructura de datos] 3. El concepto de lista enlazada y la implementación de sus operaciones básicas

3. Lista enlazada

Una lista enlazada es una estructura que almacena datos en forma de nodos, y un nodo generalmente consta de un campo de datos (datos) y un campo de puntero (siguiente), que se utilizan para almacenar datos y apuntar a la ubicación del siguiente nodo, respectivamente.

Comúnmente, hay una lista enlazada simple, una lista enlazada doble, una lista enlazada circular.

Por lo general, hay dos tipos de listas enlazadas: nodos con encabezado y nodos sin encabezado.

¿Por qué necesita un nodo de encabezado?

Cuando no hay un nodo principal, el puntero del encabezado debe modificarse al insertar y eliminar en la parte superior, y el siguiente campo del nodo predecesor se modifica al insertar y eliminar en otras posiciones. Las dos operaciones deben manejarse por separado. Por lo tanto, para operar de manera uniforme, generalmente usamos un nodo de cabeza virtual, que en sí mismo no almacena datos.

3.1, lista enlazada simple

Definición de lista enlazada individualmente:

public class Node{
    
    
	T data;
	Node next;
}

Implementación de lista enlazada simple y operaciones básicas:

Composición básica:

  • definición de nodo
  • Método de construcción
  • get(index): Obtiene el valor del nodo index-th en la lista enlazada. Devuelve -1 si el índice no es válido.
  • añadirAtHead(valor):
  • addAtTail (val)
  • addAtIndex (índice, selección) :
  • deleteAtIndex(índice):
/**结点定义*/
public class ListNode {
    
    
  int val;
  ListNode next;
  ListNode(int x) {
    
     val = x; }
}

class MyLinkedList {
    
    
  
    int size;
    ListNode head;

    /** Initialize your data structure here. */
    public MyLinkedList() {
    
    
        size = 0;
        head = new ListNode(0);
    }
    
    /** 获得指定位置的结点的值. */
    public int get(int index) {
    
    
        if(index<0 || index>=size)return -1;
        ListNode curr = head;
        // 链表只能一步步移动到指定位置
        for(int i=0;i<index+1;++i){
    
    
            curr = curr.next;
        }
        return curr.val;
    }
    
 /**将元素插入头结点*/
    public void addAtHead(int val) {
    
    
        addAtIndex(0,val);
    }
    
    /**将元素插入尾结点*/
    public void addAtTail(int val) {
    
    
        addAtIndex(size,val);
    }
    
     /**在指定索引处插入元素*/
    public void addAtIndex(int index, int val) {
    
    
        if(index>size) return; //大于size不会插入,直接退出
        if(index<0){
    
     //小于0,在头部插入
            index = 0;
        }
        //等于链表长度,在尾部(index=size)插入;在size范围内,在index出插入
        ++size;
        // 插入位置的前一个节点
        ListNode pred = head;
        // 移动到插入位置
        for(int i =0;i<index;++i){
    
    
            pred = pred.next;
        }
        ListNode toAdd = new ListNode(val);
        toAdd.next = pred.next;
        pred.next = toAdd;
    }
    
    /** 删除指定索引的结点 */
    public void deleteAtIndex(int index) {
    
    
        if(index<0 || index>=size)return ;
        size--;
        ListNode pred = head;
        for(int i =0;i<index;++i){
    
    
            pred = pred.next;
        }
        pred.next = pred.next.next;
    }
}

3.2, lista de doble enlace

Una lista con enlaces dobles puede resolver el inconveniente de que una lista con enlaces simples solo puede operar en una dirección. Se sacrifica el espacio de almacenamiento y se mejora la velocidad de operación.

Definición de lista doble enlazada:

public class Node{
    
    
	T data;
	Node pre;
	Node next;
}

La implementación de listas doblemente enlazadas es la operación básica:

public class ListNode{
    
    
    int val;
    ListNode prev;
    ListNode next;
    ListNode(int x){
    
    
        val = x;
    }
}

class MyLinkedList{
    
    
    int size;
    ListNode head,tail; //设置一个头结点和一个尾结点
    public MyLinkedList(){
    
    
        size = 0;
        head = new ListNode(0);
        tail = new ListNode(0);
        head.next = tail;
        tail.prev = head;
    }
    
    public int get(int index){
    
    
        if(index < 0 || index>=size) return -1;
        ListNode curr = head;
        //根据位置选择是从头还是尾部开始查找
        if(index+1 < size-index){
    
    
            for(int i = 0;i<index+1;++i) curr = curr.next;
        }else{
    
    
            curr = tail;
            for(int i = 0;i<size-index;++i) curr = curr.prev;
        }
        return curr.val;
    }
    
    public void addAtHead(int val){
    
    
        ListNode pred = head,succ = head.next;
        ++size;
        ListNode toAdd = new ListNode(val);
        toAdd.prev = pred;
        toAdd.next = succ;
        pred.next = toAdd;
        succ.prev = toAdd;
    }
    public void addAtTail(int val){
    
    
        ListNode succ = tail,pred = tail.prev;
        ++size;
        ListNode toAdd = new ListNode(val);
        toAdd.prev = pred;
        toAdd.next = succ;
        pred.next = toAdd;
        succ.prev = toAdd;
    }
    
    public void addAtIndex(int index,int val){
    
    
        if(index>size) return;
        if(index<0) index = 0;
        
        ListNode pred,succ;
        if(index<size-index){
    
    
            pred = head;
            for(int i = 0;i<index;++i)pred = pred.next;
            succ = pred.next;
        }else{
    
    
            succ = tail;
            for(int i = 0;i<size-index;++i)succ = succ.prev;
            pred = succ.prev;
        }
        ++size;
        ListNode toAdd = new ListNode(val);
        toAdd.prev = pred;
        toAdd.next = succ;
        pred.next = toAdd;
        succ.prev = toAdd;
    }
    public void deleteAtIndex(int index){
    
    
        if(index<0 || index>=size) return;

        ListNode pred,succ;
        if(index<size-index){
    
    
            pred = head;
            for(int i = 0;i<index;++i)pred = pred.next;
            succ = pred.next.next;
        }else{
    
    
            succ = tail;
            for(int i = 0;i<size-index-1;++i)succ = succ.prev;
            pred = succ.prev.prev;
        }

        --size;
        pred.next = succ;
        succ.prev = pred;
    }
}

3.3, lista enlazada circular

lista circular enlazada simple, lista circular doblemente enlazada

Supongo que te gusta

Origin blog.csdn.net/qq_40589204/article/details/119213882
Recomendado
Clasificación