Linked List en JavaScript: Ejemplos Fáciles de Entender 2025

Linked List en JavaScript: Ejemplos Fáciles de Entender 2025

juan correa

Juan Correa

Desarrollador de Software Senior

Si estás preparándote para entrevistas técnicas o quieres reforzar tus fundamentos en estructuras de datos, entender cómo funcionan las linked lists (listas enlazadas) en JavaScript es uno de los primeros pasos que debes dar.

En este post encontrarás explicaciones simples, ejemplos claros y casos de uso reales que te ayudarán a dominar esta estructura paso a paso y sin frustraciones.

Table of Contents

Qué es Linked List

Una linked list es una estructura de datos que consiste en una lista de nodos, donde cada nodo está enlazado al siguiente.

Puedes imaginarlo como un tren de vagones, donde cada vagón (nodo) tiene un enlace (puntero) al siguiente vagón.

Ejemplo de Linked List usando un tren de vagones
Ejemplo de Linked List usando un tren de vagones

Un tren con vagones es un buen ejemplo porque:

  • Cada vagón puede tener un contenido (valor) y un enlace al siguiente vagón.
  • Puedes agregar o quitar vagones fácilmente sin afectar a los demás.
  • Todo tren tiene un primer vagón (cabeza) y un último vagón (cola).

Para qué sirve Linked List

Si te estás preguntando: "¿Esto de qué me sirve?", aquí tienes un ejemplo:

Si tienes un array de 100 elementos y quieres insertar un nuevo elemento en la posición 50, ¿qué tendrías que hacer para no sobreescribir el elemento actual?

const arr = [1, 2, 3, 4, 5, ... , 100]
// insertar un nuevo elemento en la posición 50 sin sobreescribir el actual

Pues tendrías que mover todos los elementos subsiguientes de la posición 50 a la derecha.

¿Y qué tiene de malo eso?

Si el array no va a cambiar de tamaño con el tiempo y no tiene millones de elementos, realmente no es un problema.

Pero si el tamaño del array puede ser de cientos a millones de elementos, entonces sí que podría serlo.

¿Por qué?

Porque si tienes un array de 1 millón de elementos y quieres insertar un nuevo elemento en la posición 500.000, tendrías que mover 500.000 elementos a la derecha.

El peor escenario sería que quisieras insertar un nuevo elemento al principio del array, lo que significaría mover 1 millón de elementos a la derecha.

Si representamos como n el número de elementos en el array, diríamos que tendríamos que mover n elementos a la derecha.

En términos de complejidad en Big O notation, esto sería O(n), donde n es el número de elementos en el array.

Este es un tipo de problema que puede surgir en entrevistas técnicas, y es donde las linked lists pueden ser útiles.

Ventajas y Desventajas de Linked List VS Array

Las ventajas de usar linked lists respecto a un array son:

  • Inserciones y eliminaciones rápidas: Puedes insertar o eliminar elementos en cualquier parte de la lista sin mover otros elementos.
  • Uso eficiente de memoria: No necesitas reservar espacio para un número fijo de elementos, como en un array.
  • Tamaño dinámico: Puedes agregar o eliminar elementos sin preocuparte por el tamaño del array.

Las desventajas son:

  • Acceso lento: No puedes acceder a un elemento directamente por su índice, como en un array. Tienes que recorrer la lista desde el principio.
  • Mayor uso de memoria: Cada nodo necesita almacenar un puntero al siguiente nodo, cosa que no necesitas en un array debido a su estructura contigua.

En términos de complejidad en Big O notation, las operaciones más comunes son:

OperaciónLinked ListArray
Acceso a un elementoO(n) (recorres la lista)O(1) (por índice)
Insertar o remover al principioO(1)O(n)
Insertar o remover al finalO(1)O(n)
Insertar o remover en medioO(n)O(n)
BúsquedaO(n)O(n)

Como puedes ver, las linked lists son lo opuesto a los arrays en cuanto a acceso y búsqueda.

Podemos resumir que:

  • Si tus operaciones más frecuentes son inserciones y eliminaciones, las linked lists son una buena opción.
  • Si tus operaciones más frecuentes son accesos y búsquedas, los arrays son una mejor opción.

Por cierto, si lo que quieres es lograr búsquedas rápidas, puedes usar un hashmap en JavaScript para hacer búsquedas en tiempo constante u O(1).

Ahora que sabes qué son las linked lists y cuándo usarlas, veamos cómo implementarlas en JavaScript.

Tipos de Linked List

Los tipos de linked lists más comunes son:

  • Singly Linked List: Cada nodo tiene un puntero al siguiente nodo.
  • Doubly Linked List: Cada nodo tiene un puntero al siguiente y al anterior nodo.
  • Circular Linked List: El último nodo apunta al primer nodo, formando un ciclo.

Aprende Algoritmos y Estructuras de Datos

Este artículo es parte de un esfuerzo continuo por compartir contenido claro y práctico sobre algoritmos, estructuras de datos y preparación técnica.

Si quieres recibir este tipo de recursos directamente en tu correo, puedes unirte a mi newsletter. Sin spam. Solo contenido útil para desarrolladores que quieren crecer.

👉 Unirme a la newsletter

Al unirte vas a recibir un regalo sorpresa. Si quieres descubrirlo, dale click al link de arriba.

Ejemplo de Singly Linked List en JavaScript (Paso a Paso)

Te muestro una implementación básica de una singly linked list, que es la más común y fácil de entender.

Considera que existen diferentes maneras de resolver el mismo problema, y que esta es una de ellas.

Definición de un nodo

Antes dijimos que una linked list se compone de nodos, y que cada nodo tiene un valor y un puntero al siguiente.

En JavaScript, podemos representar un nodo como una clase:

class Node {
  constructor(data) {
    this.data = data
    this.nextNode = undefined
  }
}

El valor del nodo se almacena en la propiedad data, y el puntero al siguiente nodo se almacena en la propiedad nextNode.

Para usarlo, sería:

const node1 = new Node(1)
const node2 = new Node(2)

node1.nextNode = node2

console.log(node1) // Node { data: 1, nextNode: Node { data: 2, nextNode: null } }

Ahora vamos a crear la estructura que va a controlar los nodos en forma de una linked list.

Definición de la lista enlazada inicial

Antes dijimos que una lista enlazada tiene una cabeza (head) que apunta al primer nodo. Al crear la lista, la cabeza estará vacía.

class LinkedList {
  constructor() {
    this.head = undefined
  }
}

Más adelante, vamos a agregarle métodos para insertar, buscar y eliminar nodos.

Definición de isEmpty()

Podemos crear métodos convenientes que faciliten la experiencia de desarrollo, como saber si la lista está vacía:

class LinkedList {
  constructor() {
    this.head = undefined
  }

  isEmpty() {
    return this.head === undefined
  }
}

Puedes usarlo así:

const list = new LinkedList()
console.log(list.isEmpty()) // true

Definición de add()

Ahora vamos a comenzar a insertar nodos en la lista.

La manera más sencilla de hacerlo es insertando nodos al final de la lista, indepndientemente de si la lista está vacía o no. Para ello, vamos a crear un método add que reciba un valor y lo inserte al final de la lista.

class LinkedList {
  constructor() {
    this.head = undefined
  }

  isEmpty() {
    return this.head === undefined
  }

  add(data) {
    // creamos un nuevo nodo con el valor recibido
    const node = new Node(data)

    // el nuevo nodo va a apuntar a la cabeza actual de la lista
    // ya sea que head sea undefined o un nodo existente
    node.nextNode = this.head

    // ahora la cabeza de la lista va a ser el nuevo nodo
    this.head = node
  }
}

Puedes usarlo así:

const list = new LinkedList()

console.log(list.isEmpty()) // true

list.add(1)

console.log(list.isEmpty()) // false

list.add(2)

console.log(list) // LinkedList { head: Node { value: 2, nextNode: Node { value: 1, nextNode: null } } }

Genial, ya estamos insertando nodos en la lista con una complejidad de O(1), porque no depende del tamaño de la lista para agregar un nuevo nodo. Siempre lo agregamos al principio de la lista, respetando los nodos anteriores.

Otro método útil que podemos hacer es buscar un nodo por su valor.

En este caso, sí tenemos que recorrer la lista hasta encontrar el nodo que buscamos o retornar undefined si no existe el valor.

search(data) {
  // variable auxiliar para tener la referencia al nodo actual
  // al inicio es el nodo de la cabeza de la lista
  let current = this.head

  // mientras haya un nodo actual
  while (current) {
    // si el nodo actual tiene el valor que buscamos
    // retornamos el nodo actual y se termina la ejecución de la función
    if (current.data === data) {
      return current
    }

    // si no, asignamos el siguiente nodo a la variable auxiliar
    // y seguimos buscando hasta que current sea undefined
    current = current.nextNode
  }

  // si recorrimos toda la lista y no encontramos el valor, entonces no existe el valor
  return undefined
}

No te preocupes si no entiendes del todo el código al principio. Es normal y a mí me pasó. Lo importante es que entiendas la lógica detrás de la implementación.

La lista enlazada tiene una cabeza (head) que apunta al primer nodo. Luego, cada nodo tiene un puntero al siguiente nodo.

Cuando buscamos un nodo por su valor, comenzamos desde la cabeza y vamos recorriendo la lista hasta encontrar el nodo que buscamos.

Lo puedes usar así:

const list = new LinkedList()
list.add(1)
list.add(2)
list.add(3)
list.add(4)
list.add(5)

console.log(list.search(3)) // Node { value: 3, nextNode: Node { value: 2, nextNode: [Node] } }
console.log(list.search(6)) // undefined

En el mejor escenario, si el nodo que buscamos es el primero, la complejidad es O(1) porque no tenemos que recorrer la lista.

En el peor escenario, si el nodo que buscamos es el último o no existe, la complejidad es O(n) porque recorremos toda la lista.

Recuerda que siempre nos basamos en el peor escenario para calcular la complejidad, por lo que en este caso sería O(n).

Definición de remove()

Ahora vamos a implementar el método remove, que va a eliminar un nodo de la lista.

En este caso, vamos a incorporar el concepto de key, si consideramos que una lista enlazada puede tener los nodos enumerados de 0 a n, entonces la key sería el índice del nodo.

remove(key) {
  // si queremos eliminar el primer nodo (cabeza)
  // simplemente asignamos la cabeza al siguiente nodo
  // y finalizamos la función
  if (key === 0) {
    this.head = this.head.nextNode
    return
  }

  // si no, tenemos que recorrer la lista hasta el nodo que queremos eliminar

  // variable auxiliar para tener la referencia al nodo actual
  let current = this.head

  // es una copia del índice que vamos a eliminar.
  // Se usará para moverse dentro de la lista.
  let count = key

  // mueve el puntero current hasta que esté justo antes del nodo a eliminar
  // ejemplo: si key === 2, este bucle parará con current apuntando al nodo con índice 1.
  while (count > 1) {
    // restamos - 1 a count hasta llegar a 0
    // que significa que hemos llegado al nodo que queremos eliminar
    count -= 1

    // current va a ser igual al siguiente nodo
    // hasta llegar al nodo que queremos eliminar
    current = current.nextNode
  }

  // saltamos el nodo objetivo

  // es el nodo justo antes del que queremos eliminar.
  const prevNode = current

  // es el que está después del nodo que se va a eliminar.
  const nextNode = current.nextNode.nextNode

  // luego simplemente conectamos prevNode.nextNode a nextNode, "saltando" el nodo intermedio, y así lo eliminamos de la lista.
  prevNode.nextNode = nextNode
}

En el primer caso, si el índice a eliminar es 0, simplemente "saltamos" el nodo actual que está en la cabeza. Esto se hace actualizando this.head para que ahora apunte al siguiente nodo.

Singly Linked List Completa

Así queda la implementación completa de una singly linked list que hemos visto hasta ahora:

class Node {
  constructor(data) {
    this.data = data
    this.nextNode = undefined
  }
}

class LinkedList {
  constructor() {
    this.head = undefined
  }

  isEmpty() {
    return this.head === undefined
  }

  size() {
    let current = this.head
    let count = 0

    while (current) {
      count += 1
      current = current.nextNode
    }

    return count
  }

  add(data) {
    const node = new Node(data)
    node.nextNode = this.head
    this.head = node
  }

  remove(key) {
    if (key === 0) {
      this.head = this.head.nextNode
      return
    }

    let current = this.head
    let count = key

    while (count > 1) {
      count -= 1
      current = current.nextNode
    }

    const prevNode = current
    const nextNode = current.nextNode.nextNode
    prevNode.nextNode = nextNode
  }

  search(data) {
    let current = this.head

    while (current) {
      if (current.data === data) {
        return current
      }

      current = current.nextNode
    }

    return undefined
  }
}

Aún quedan algunos métodos que podemos agregarle a la lista enlazada, como:

  • size(): para saber cuántos nodos hay en la lista.
  • reverse(): para invertir la lista.
  • remove(): para eliminar un nodo por su valor.
  • insertAt(): para insertar un nodo en una posición específica.

Te invito a que lo intentes tú mismo. Con los ejemplos que hemos visto, ya tienes la base para hacerlo.

Más Recursos Para Pasar Entrevistas y Aprender

Recursos de Developero:

Con estos contenidos, estás más cerca de convertirte en ese perfil técnico que todas las empresas quieren.

Otros recursos:

Sobre el autor

Soy Juan Correa, un desarrollador con experiencia construyendo productos reales y enseñando a otros profesionales.

Escribo contenido práctico para ayudarte a pasar entrevistas técnicas, mejorar como dev y tomar mejores decisiones en tu código.

Conecta conmigo en LinkedIn o YouTube si buscas un consejo, quieres seguir aprendiendo sobre desarrollo web, entrevistas técnicas y más.