摘要:什么是雙鏈表上一篇實(shí)戰(zhàn)數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)之單鏈表說到單鏈表由一個(gè)一個(gè)的作為節(jié)點(diǎn)的對象構(gòu)成的,每一個(gè)節(jié)點(diǎn)都有指向下一個(gè)節(jié)點(diǎn)的指針,最后一個(gè)節(jié)點(diǎn)的指針域指向空。
什么是雙鏈表?
上一篇實(shí)戰(zhàn)PHP數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)之單鏈表說到
單鏈表由一個(gè)一個(gè)的作為節(jié)點(diǎn)的對象構(gòu)成的,每一個(gè)節(jié)點(diǎn)都有指向下一個(gè)節(jié)點(diǎn)的指針,最后一個(gè)節(jié)點(diǎn)的指針域指向空。每個(gè)節(jié)點(diǎn)可以存儲(chǔ)任何數(shù)據(jù)類型。
而雙鏈表每個(gè)節(jié)點(diǎn)有兩個(gè)指針域,分別指向前驅(qū)和后繼節(jié)點(diǎn)。單鏈表是單向的,而雙鏈表是雙向的。
常見操作對雙鏈表我們常見的操作有如下:
insert
insertBefore
insertAfter
insertAtFirst
insertAtLast
deleteFirst
deleteLast
delete
reverse
getNthNode
...
PHP語言實(shí)現(xiàn)首先我們根據(jù)定義實(shí)現(xiàn)一個(gè)雙鏈表的ListNode類。
class ListNode { public $data = null; public $next = null; public $prev = null; public function __construct(string $data) { $this->data = $data; } }
再來看鏈表類,首先需要3個(gè)私有屬性,分別是頭節(jié)點(diǎn)、尾巴節(jié)點(diǎn)和長度。
class DoubleLinkedList { private $head = null; private $last = null; private $length = 0; }
接下來還是老規(guī)矩,直接看如何實(shí)現(xiàn)第一個(gè)即常用的插入,這是是一個(gè)平均時(shí)間復(fù)雜度為O(n)的操作。
/** * 插入一個(gè)節(jié)點(diǎn) * @param string|null $data * @return bool * complexity O(n) */ public function insert(string $data = null) { $newNode = new ListNode($data); if ($this->head) { $currentNode = $this->head; while ($currentNode) { if ($currentNode->next === null) { $currentNode->next = $newNode; $newNode->prev = $currentNode; $this->last = $newNode; $this->length++; return true; } $currentNode = $currentNode->next; } } else { $this->head = &$newNode; $this->last = $newNode; $this->length++; return true; } }
再來看如何刪除節(jié)點(diǎn)。
/** * 刪除一個(gè)節(jié)點(diǎn) * @param string $data * @return bool|ListNode * complexity O(n) */ public function delete(string $query = null) { if ($this->head) { $currentNode = $this->head; $prevNode = null; while ($currentNode) { if ($currentNode->data === $query) { if ($nextNode = $currentNode->next) { if ($prevNode) { $prevNode->next = $nextNode; $nextNode->prev = $prevNode; } else { $this->head = $nextNode; $nextNode->prev = null; } unset($currentNode); } else { if ($prevNode) { $this->last = $prevNode; $prevNode->next = null; unset($currentNode); } else { $this->head = null; $this->last = null; } } $this->length--; return true; } $prevNode = $currentNode; $currentNode = $currentNode->next; } } return false; }
反轉(zhuǎn)雙鏈表也不是很復(fù)雜。
public function reverse() { if ($this->head !== null) { if ($this->head->next !== null) { $reversedList = null; $currentNode = $this->head; while ($currentNode !== null) { $next = $currentNode->next; $currentNode->next = $reversedList; $currentNode->prev = $next; $reversedList = $currentNode; $currentNode = $next; } $this->last = $this->head; $this->head = $reversedList; } } }
雙鏈表其他操作的詳細(xì)實(shí)現(xiàn)可以參考 這里。
雙鏈表是鏈表這種鏈?zhǔn)酱嫒?shù)據(jù)結(jié)構(gòu)中相對于單鏈表比較特殊的部分,同樣屬于鏈表結(jié)構(gòu)的還有單鏈表,環(huán)形鏈表和多鏈表。
專題系列PHP基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)專題系列目錄地址:https://github.com/... 主要使用PHP語法總結(jié)基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)和算法。還有我們?nèi)粘HP開發(fā)中容易忽略的基礎(chǔ)知識和現(xiàn)代PHP開發(fā)中關(guān)于規(guī)范、部署、優(yōu)化的一些實(shí)戰(zhàn)性建議,同時(shí)還有對Javascript語言特點(diǎn)的深入研究。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/28817.html