Menu
Coddy logo textTech

Lista enlazada

Última actualización

Una lista enlazada almacena una secuencia como una cadena de nodos, donde cada nodo guarda un valor y un puntero al siguiente nodo. A diferencia de un arreglo, los nodos no son contiguos en memoria: sigues los punteros next para recorrer la lista. Pulsa reproducir arriba para ver cómo se enlazan nodos al principio y al final, cómo se busca un valor recorriendo la cadena y cómo se elimina un nodo reconectando un puntero.

Insertar o eliminar al principio es O(1) porque solo reapuntas la cabeza. Llegar a una posición en el medio o al final es O(n) porque primero debes recorrer hasta allí. Ese compromiso -extremos baratos, sin acceso aleatorio- es lo que distingue a una lista enlazada de un arreglo.

Complejidad temporal

OperaciónComplejidadNotas
Insertar al principioO(1)Reapuntar la cabeza
Insertar al finalO(n)Recorrer primero hasta el final (O(1) con un puntero al final)
BuscarO(n)Seguir los punteros next
Eliminar la cabezaO(1)Reapuntar la cabeza más allá de ella
Acceso por índiceO(n)Sin acceso aleatorio

Lista enlazada vs arreglo

AspectoLista enlazadaArreglo
MemoriaNodos dispersos + punterosBloque contiguo
Acceso aleatorioO(n)O(1)
Insertar/eliminar al frenteO(1)O(n) (desplazamiento)
Amigabilidad con la cachéMalaBuena

Ejemplo resuelto

Construir la lista [10, 20], anteponer 5 y luego eliminar 20:

PasoEstructuraAcción
Iniciohead -> nullLista vacía
Insertar al principio 10head -> 10 -> nullReapuntar la cabeza a un nuevo nodo cuyo next es la cabeza anterior (null)
Insertar al final 20head -> 10 -> 20 -> nullRecorrer hasta el nodo 10, poner su next en un nuevo nodo 20
Insertar al principio 5head -> 5 -> 10 -> 20 -> nullEl nuevo nodo 5 apunta a la antigua cabeza 10; la cabeza ahora apunta a 5
Eliminar 20head -> 5 -> 10 -> nullRecorrer hasta 10, poner su next de 20 a null; el nodo 20 queda desenlazado

Cuándo usar una lista enlazada

Úsala cuandoEvítala cuando
Insertas o eliminas en los extremos (o en un nodo que ya tienes) mucho más de lo que indexasNecesitas acceso aleatorio rápido por posición (indexación O(1))
El tamaño cambia mucho y no quieres coste de redimensionar/copiarRecorres bucles ajustados donde la localidad de caché domina el rendimiento
Estás construyendo una cola, una pila o una lista de adyacenciaLa memoria es escasa: cada nodo paga un puntero extra por elemento
Necesitas referencias estables a nodos que sobreviven a inserciones en otros lugaresMayormente lees y rara vez modificas, así que un arreglo es más simple y rápido

Código de Linked List

Una implementación limpia y ejecutable de Linked List en Python, JavaScript, Java, C++, C. Elige un lenguaje, copia el código o ábrelo ya cargado en el Playground de Coddy.

Código de Linked List en Python

Python
1class Node:2    def __init__(self, value):3        self.value = value4        self.next = None5
6
7class LinkedList:8    def __init__(self):9        self.head = None10
11    def append(self, value):12        node = Node(value)13        if self.head is None:14            self.head = node15            return16        current = self.head17        while current.next:18            current = current.next19        current.next = node20
21    def find(self, value):22        current = self.head23        while current:24            if current.value == value:25                return True26            current = current.next27        return False28
29    def delete(self, value):30        # Re-link the previous node around the match31        current, prev = self.head, None32        while current:33            if current.value == value:34                if prev is None:35                    self.head = current.next36                else:37                    prev.next = current.next38                return True39            prev, current = current, current.next40        return False41
42    def __str__(self):43        values, current = [], self.head44        while current:45            values.append(str(current.value))46            current = current.next47        return " -> ".join(values) + " -> None"48
49
50lst = LinkedList()51for value in [3, 7, 1, 9]:52    lst.append(value)53
54print("List:    ", lst)55print("find(7): ", lst.find(7))56lst.delete(1)57print("After delete(1):", lst)
Ejecuta este código en el Playground de Python

Preguntas frecuentes sobre listas enlazadas

¿Cuál es la diferencia entre una lista enlazada y un arreglo?
Un arreglo almacena los elementos en un único bloque contiguo, lo que da acceso aleatorio O(1) pero inserciones/eliminaciones O(n) que desplazan elementos. Una lista enlazada almacena nodos en cualquier lugar de la memoria conectados por punteros, lo que da inserciones/eliminaciones O(1) en una posición conocida pero acceso O(n) ya que debes recorrer la cadena.
¿Cuándo debería usar una lista enlazada?
Las listas enlazadas brillan cuando insertas o eliminas con frecuencia en los extremos (o en un nodo del que ya tienes una referencia) y rara vez necesitas acceso aleatorio, por ejemplo colas, pilas, listas de adyacencia y cachés LRU. Si necesitas acceso indexado rápido, un arreglo o arreglo dinámico suele ser mejor.
¿Cuál es la complejidad temporal de una lista enlazada?
Insertar o eliminar en la cabeza es O(1). Buscar, o llegar al final sin un puntero al final, es O(n) porque sigues los punteros next uno por uno. No hay acceso aleatorio O(1): indexar en una lista enlazada es O(n).
¿Cuál es la diferencia entre una lista simplemente enlazada y una doblemente enlazada?
Una lista simplemente enlazada almacena solo un puntero next por nodo, así que puedes recorrer en una dirección y eliminar un nodo requiere una referencia a su predecesor. Una lista doblemente enlazada añade un puntero prev, permitiendo el recorrido hacia atrás y la eliminación O(1) de un nodo que ya tienes, a costa de un puntero extra por nodo y más gestión en cada inserción y eliminación.
¿Por qué insertar al final es O(n) si insertar al principio es O(1)?
Insertar al principio solo reconecta el puntero head, que es trabajo constante. Llegar al final significa seguir los punteros next desde la cabeza hasta el extremo, lo cual es O(n). Mantener un puntero tail separado hace que la inserción al final también sea O(1), por lo que las listas del mundo real a menudo rastrean ambos extremos.
¿Tienen las listas enlazadas inserción O(1) en todas partes?
No, esa es una idea equivocada común. La inserción en sí es O(1) solo una vez que ya tienes un puntero al nodo después del cual insertas. Encontrar esa posición por valor o índice sigue costando O(n) porque debes recorrer la cadena para llegar allí.
Coddy programming languages illustration

Domina los algoritmos con Coddy

COMENZAR