Ответ
Да, работал. Хотя в PHP нет нативной необходимости часто реализовывать их с нуля (в отличие от C++), понимание принципов работы связных списков критически важно для алгоритмического мышления. Я реализовывал их для решения специфических задач и лучшего понимания структур данных.
Моя реализация двусвязного списка для задачи кэширования (LRU Cache):
class ListNode {
public $key;
public $value;
public $prev = null;
public $next = null;
public function __construct($key, $value) {
$this->key = $key;
$this->value = $value;
}
}
class LRUCache {
private $capacity;
private $map = []; // Хеш-таблица для быстрого доступа
private $head; // Псевдо-голова (самый новый)
private $tail; // Псевдо-хвост (самый старый)
public function __construct($capacity) {
$this->capacity = $capacity;
$this->head = new ListNode(null, null);
$this->tail = new ListNode(null, null);
$this->head->next = $this->tail;
$this->tail->prev = $this->head;
}
private function _addToHead($node) {
// Вставляет узел сразу после псевдо-головы
$node->prev = $this->head;
$node->next = $this->head->next;
$this->head->next->prev = $node;
$this->head->next = $node;
}
private function _removeNode($node) {
// Удаляет узел из списка
$prev = $node->prev;
$next = $node->next;
$prev->next = $next;
$next->prev = $prev;
}
public function get($key) {
if (!isset($this->map[$key])) return -1;
$node = $this->map[$key];
$this->_removeNode($node); // Удаляем из текущей позиции
$this->_addToHead($node); // И добавляем в голову как самый новый
return $node->value;
}
// ... методы put и другие
}
Ключевые преимущества и где я их применял:
- Динамический размер и O(1) вставка/удаление в начало/конец делают их идеальными для реализации очередей (FIFO) или стеков (LIFO). В PHP для этого часто используют
SplDoublyLinkedListиз стандартной библиотеки (SPL). - Алгоритмические задачи: Многие задачи на LeetCode или Codility (например, разворот списка, обнаружение цикла, слияние отсортированных списков) требуют работы со связными списками.
- Понимание основ: Работа со списками помогает глубже понять, как работают более сложные структуры, такие как деревья и графы.
Ответ 18+ 🔞
А, ну ты про связные списки спрашиваешь! Да, работал, конечно. Хотя в PHP, если честно, нихуя не нужно их с нуля городить каждый день — не то что на каком-нибудь C++, где без этого нихуя не сделаешь. Но понимать, как эта штука работает изнутри — это, блядь, критически важно для мозга. Без этого ты как мартышлюшка с гранатой — код пишешь, а что внутри происходит, нихуя не вдупляешь. Я их реализовывал, когда нужно было специфические задачи решать или просто мозги прокачать.
Вот, смотри, как я двусвязный список для кэша (LRU) делал:
class ListNode {
public $key;
public $value;
public $prev = null;
public $next = null;
public function __construct($key, $value) {
$this->key = $key;
$this->value = $value;
}
}
class LRUCache {
private $capacity;
private $map = []; // Хеш-таблица для быстрого доступа
private $head; // Псевдо-голова (самый новый)
private $tail; // Псевдо-хвост (самый старый)
public function __construct($capacity) {
$this->capacity = $capacity;
$this->head = new ListNode(null, null);
$this->tail = new ListNode(null, null);
$this->head->next = $this->tail;
$this->tail->prev = $this->head;
}
private function _addToHead($node) {
// Вставляет узел сразу после псевдо-головы
$node->prev = $this->head;
$node->next = $this->head->next;
$this->head->next->prev = $node;
$this->head->next = $node;
}
private function _removeNode($node) {
// Удаляет узел из списка
$prev = $node->prev;
$next = $node->next;
$prev->next = $next;
$next->prev = $prev;
}
public function get($key) {
if (!isset($this->map[$key])) return -1;
$node = $this->map[$key];
$this->_removeNode($node); // Удаляем из текущей позиции
$this->_addToHead($node); // И добавляем в голову как самый новый
return $node->value;
}
// ... методы put и другие
}
А теперь, ёпта, главное — зачем это всё, и где я это применял:
- Динамический размер и O(1) на вставку/удаление — вот это, блядь, пиздец как удобно, когда тебе нужна очередь (FIFO) или стек (LIFO). В PHP, конечно, для этого есть готовая
SplDoublyLinkedListиз коробки, но понимать, как она устроена — это уже вопрос не технический, а, блядь, самоуважения. - Алгоритмические задачки: Ну тут вообще пиздец. Половина задач на LeetCode или Codility (типа развернуть список, найти цикл, смерджить отсортированные списки) — это сплошные ёбаные связные списки. Без них ты просто, как тот самый пидарас шерстяной, на первом же собеседовании вылетишь.
- Понимание основ, ёпта: Вот это самое главное. Пока ты не поковыряешься руками с этими
nextиprev, ты нихуя не поймёшь, как работают более сложные штуки вроде деревьев или графов. Это как фундамент, блядь. Без него твоё знание — это доверия ебать ноль, один пшик.