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

Что такое односвязный список?

1.0 Junior🔥 131 комментариев
#Алгоритмы и структуры данных

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

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

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

Что такое односвязный список?

Односвязный список — это фундаментальная структура данных в программировании, представляющая собой линейную коллекцию элементов (узлов), где каждый элемент хранит не только свои данные, но и ссылку (pointer или link) на следующий элемент в последовательности. Это создает цепочку узлов, "связывающую" их друг с другом. В отличие от массива, элементы списка не располагаются в непрерывном блоке памяти и их порядок определяется исключительно этими ссылками.

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

Каждый узел односвязного списка в PHP обычно реализуется как объект класса и содержит два ключевых поля:

class ListNode {
    public $data; // Данные, которые хранит узел (может быть любым типом: число, строка, объект)
    public $next; // Ссылка на следующий узел в списке (объект ListNode или null)

    public function __construct($data) {
        $this->data = $data;
        $this->next = null;
    }
}

Список как целое управляется через ссылку на его первый элемент — head (голову).

class SinglyLinkedList {
    private $head; // Ссылка на первый узел списка

    public function __construct() {
        $this->head = null;
    }

    // ... методы для операций: добавление, удаление, поиск
}

Ключевые характеристики и свойства

  • Динамический размер: Список может расти и сокращаться во время выполнения программы без необходимости предварительного выделения фиксированного объема памяти, как в массиве.
  • Непрерывность памяти: Узлы могут располагаться в совершенно разных участках памяти. Это может снизить эффективность кэша процессора по сравнению с массивами.
  • Последовательный доступ: Для доступа к элементу, например, на позиции N, необходимо начать с head и последовательно пройти через N-1 узлов (next). Это делает операции доступа по индексу O(n) по времени, в отличие от массива с O(1).
  • Эффективные операции в начале списка: Добавление или удаление элемента в начале списка (head) — очень быстрая операция O(1).
  • "Хвост" списка: Последний узел имеет ссылку next, равную null. Это маркер конца списка.

Основные операции и их реализация в PHP

1. Добавление элемента в начало (prepend)

Операция выполняется очень быстро.

public function prepend($data) {
    $newNode = new ListNode($data);
    $newNote->next = $this->head; // Новый узёл указывает на старую голову
    $this->head = $newNode;       // Головой списка становится новый узёл
}

2. Добавление элемента в конец (append)

Для этого необходимо найти последний узел, пройдя по всей цепочке.

public function append($data) {
    $newNode = new ListNode($data);
    if ($this->head === null) {
        $this->head = $newNode;
        return;
    }
    $current = $this->head;
    while ($current->next !== null) {
        $current = $current->next;
    }
    $current->next = $newNode;
}

3. Поиск элемента

Демонстрирует принцип последовательного доступа.

public function find($value) {
    $current = $this->head;
    while ($current !== null) {
        if ($current->data === $value) {
            return $current;
        }
        $current = $current->next;
    }
    return null; // Элемент не найден
}

4. Удаление элемента (по значению)

Удаление требует корректной перелинковки узлов.

public function delete($value) {
    if ($this->head === null) return;

    // Если удаляется головной элемент
    if ($this->head->data === $value) {
        $this->head = $this->head->next;
        return;
    }

    $current = $this->head;
    while ($current->next !== null && $current->next->data !== $value) {
        $current = $current->next;
    }
    if ($current->next !== null) {
        $current->next = $current->next->next; // "Перепрыгиваем" через удаляемый узёл
    }
}

Преимущества и недостатки односвязного списка

Преимущества:

  • Гибкость размера: Идеально для ситуаций, когда количество данных неизвестно заранее.
  • Эффективное добавление/удаление в начале: Критично для реализации структур типа стек (LIFO).
  • Экономия памяти при частых изменениях: Вставка/удаление в середине массива требует массового перемещения элементов, а в списке — лишь изменения нескольких ссылок (хотя поиск позиции остается затратным).

Недостатки:

  • Медленный доступ по индексу: Не подходит для частого случайного доступа к элементам.
  • Дополнительная память на ссылки: Каждый узел хранит "лишний" указатель next.
  • Невозможность обратного хода: Чтобы найти предыдущий элемент для узла X, нужно начать поиск снова с головы. Этот недостаток устраняется в двусвязном списке, где узлы хранят ссылки и на next, и на prev.

Применение односвязных списков в Backend PHP

В практике PHP backend-разработчика явные реализации односвязных списков встречаются нечасто, так как PHP предоставляет мощные встроенные массивы, которые гибко сочетают свойства списков и хэш-таблиц. Однако понимание этой структуры критически важно для:

  • Понимания фундаментальных алгоритмов (например, реверсирования списка, обнаружения циклов).
  • Решение задач на собеседованиях, где требуется демонстрация знаний структур данных.
  • Оптимизации обработки данных в специализированных модулях или при интеграции с системами, где списки являются основной структурой (например, некоторые реализации в C-расширениях).
  • Реализации очередей и стеков, где односвязный список может быть эффективным фундаментом.

Таким образом, односвязный список — это не просто абстрактная концепция, а инструмент для решения конкретных задач, где важна динамичность и эффективность операций на концах последовательности, а не случайный доступ. Его понимание формирует базу для освоения более сложных структур, таких как двусвязные списки, циклические списки и графы.