← Назад к вопросам

Что такое linked list в Node.js?

2.2 Middle🔥 151 комментариев
#Node.js и JavaScript#Алгоритмы и структуры данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Linked List (связный список) — это структура данных, состоящая из узлов, где каждый узел содержит данные и ссылку на следующий узел. Это альтернатива массивам с собственными преимуществами и недостатками.

Основная структура

Узел (Node) содержит:

  • Данные (value)
  • Ссылку на следующий узел (next)
class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
    this.size = 0;
  }
  
  // Добавить в конец
  append(data) {
    const node = new Node(data);
    
    if (this.head === null) {
      this.head = node;
      this.tail = node;
    } else {
      this.tail.next = node;
      this.tail = node;
    }
    
    this.size++;
  }
  
  // Добавить в начало
  prepend(data) {
    const node = new Node(data);
    
    if (this.head === null) {
      this.head = node;
      this.tail = node;
    } else {
      node.next = this.head;
      this.head = node;
    }
    
    this.size++;
  }
  
  // Удалить по значению
  remove(data) {
    let current = this.head;
    let previous = null;
    
    while (current !== null) {
      if (current.data === data) {
        if (previous === null) {
          this.head = current.next;
        } else {
          previous.next = current.next;
        }
        this.size--;
        return;
      }
      previous = current;
      current = current.next;
    }
  }
  
  // Поиск
  find(data) {
    let current = this.head;
    
    while (current !== null) {
      if (current.data === data) return current;
      current = current.next;
    }
    
    return null;
  }
  
  // Показать все
  print() {
    let current = this.head;
    let result = '';
    
    while (current !== null) {
      result += current.data + ' -> ';
      current = current.next;
    }
    
    result += 'null';
    console.log(result);
  }
}

const list = new LinkedList();
list.append(10);
list.append(20);
list.append(30);
list.prepend(5);
list.print(); // 5 -> 10 -> 20 -> 30 -> null

Linked List vs Array

Операция | Linked List | Array

  • Вставка в начало: O(1) vs O(n) — быстро vs медленно
  • Вставка в конец: O(1) vs O(1) — одинаково
  • Удаление: O(n) vs O(n) — одинаково
  • Поиск: O(n) vs O(n) — одинаково
  • Доступ по индексу: O(n) vs O(1) — медленно vs быстро
  • Память: O(n) + n ссылок vs O(n) — больше памяти

Когда использовать Linked List:

  • Частые вставки в начало
  • Неизвестный размер заранее
  • Реализация Queue/Deque

Когда использовать Array:

  • Частые поиски и доступ по индексу
  • Изменяющийся размер (push/pop в конец)
  • Известный размер данных

Двусвязный список (Doubly Linked List)

class DoublyNode {
  constructor(data) {
    this.data = data;
    this.next = null;
    this.prev = null;
  }
}

class DoublyLinkedList {
  constructor() {
    this.head = null;
  }
  
  append(data) {
    const node = new DoublyNode(data);
    
    if (this.head === null) {
      this.head = node;
    } else {
      let current = this.head;
      while (current.next) current = current.next;
      current.next = node;
      node.prev = current;
    }
  }
  
  // Может быть легче удалять (знаем предыдущий узел)
  remove(data) {
    if (this.head === null) return;
    
    let current = this.head;
    
    while (current !== null) {
      if (current.data === data) {
        if (current.prev) {
          current.prev.next = current.next;
        } else {
          this.head = current.next;
        }
        
        if (current.next) {
          current.next.prev = current.prev;
        }
        return;
      }
      current = current.next;
    }
  }
}

Реальные примеры в Node.js

1. Реализация LRU Cache (Least Recently Used):

class LRUCache {
  constructor(maxSize) {
    this.maxSize = maxSize;
    this.list = new DoublyLinkedList();
    this.map = new Map();
  }
  
  get(key) {
    if (this.map.has(key)) {
      // Переместить в конец
      this.list.moveToEnd(key);
      return this.map.get(key);
    }
    return null;
  }
  
  put(key, value) {
    if (this.map.has(key)) {
      this.map.set(key, value);
      this.list.moveToEnd(key);
    } else {
      if (this.map.size >= this.maxSize) {
        // Удалить самый старый элемент
        const oldest = this.list.removeHead();
        this.map.delete(oldest);
      }
      
      this.list.append(key);
      this.map.set(key, value);
    }
  }
}

2. История действий (для отката):

class ActionHistory {
  constructor() {
    this.history = new LinkedList();
  }
  
  addAction(action) {
    this.history.append(action);
  }
  
  undo() {
    // Удалить последний элемент
    const current = this.history.tail;
    // В обычном LinkedList нет быстрого доступа к предпоследнему
    // Использовать DoublyLinkedList было бы лучше
  }
}

3. Граф (соседи узла):

class GraphNode {
  constructor(value) {
    this.value = value;
    this.adjacents = new LinkedList(); // соседние узлы
  }
  
  addEdge(node) {
    this.adjacents.append(node);
  }
}

const nodeA = new GraphNode('A');
const nodeB = new GraphNode('B');
nodeA.addEdge(nodeB);

4. Очередь (Queue):

class Queue {
  constructor() {
    this.list = new LinkedList();
  }
  
  enqueue(data) {
    this.list.append(data); // O(1)
  }
  
  dequeue() {
    const head = this.list.head.data;
    this.list.remove(head);
    return head; // O(1) для первого элемента
  }
}

Circular Linked List

class CircularLinkedList extends LinkedList {
  append(data) {
    const node = new Node(data);
    
    if (this.head === null) {
      this.head = node;
      this.head.next = this.head; // указывает сам на себя
    } else {
      let current = this.head;
      while (current.next !== this.head) current = current.next;
      current.next = node;
      node.next = this.head;
    }
  }
}

Когда использовать Linked List в Node.js

  • LRU Cache — кэширование с вытеснением старых элементов
  • Playlist — список песен с быстрым переходом между ними
  • Undo/Redo — история действий
  • Graph representation — представление графов
  • Очереди с частыми вставками в начало
  • Музыкальный плеер — список треков

Linked List — это важная структура данных, хотя в современном JavaScript часто используют Array с методами push/shift или Queue. Понимание Linked List критично для собеседований и оптимизации определённых алгоритмов.

Что такое linked list в Node.js? | PrepBro