標籤:常用 順序 簡單 情境 個數 結合 不同 的區別
鏈表是什嗎?
來看看維基百科給出的定義:
- 鏈表(Linked list)是一種常見的基礎資料結構,是一種線性表,但是並不會按線性順序儲存資料,而是在每一個節點裡儲存到下一個節點的指標(Pointer)。
- 由於不必須按順序儲存,鏈表在插入的時候可以達到O(1)的複雜度,比數組快得多,但是尋找一個節點或者訪問特定編號的節點則需要O(n)的時間,而順序表相應的時間複雜度分別是O(logn)和O(1)。
鏈表和數組在記憶體中的分布,大概是這樣的:
簡單點來說,鏈表和數組一樣是一種線性表的資料結構,不同之處在於,定義一個數組需要申請一塊連續的儲存空間來儲存;而鏈表恰恰相反,他並不需要一塊連續的記憶體空間,而是在每一個節點裡儲存到下一個節點的指標,通過“指標”將一組零散的記憶體塊串聯起來使用。
常見的鏈表結構有哪些?
單鏈表
單鏈表是最簡單、最常用的鏈表結構。
每個鏈表的節點除了儲存資料之外,還需要記錄鏈上的下一個結點的地址。,這個記錄下個結點地址的指標叫作後繼指標 next。
圖中其中有兩個結點是比較特殊的,它們分別是第一個結點和最後一個結點。我們習慣性地把第一個結點叫作頭結點,把最後一個結點叫作尾結點。其中,頭結點用來記錄鏈表的基地址。有了它,我們就可以遍曆得到整條鏈表。而尾結點特殊的地方是:指標不是指向下一個結點,而是指向一個空地址 NULL,表示這是鏈表上最後一個結點。
迴圈鏈表
迴圈鏈表是一種特殊的單鏈表。它跟單鏈表唯一的區別就在尾結點,迴圈鏈表的尾結點指標是指向鏈表的頭結點。如所示:
雙向鏈表
雙向鏈表在實際的軟體開發中也很常用,其結構如所示:
雙向鏈表需要額外的兩個空間來儲存後繼結點和前驅結點的地址。所以,如果儲存同樣多的資料,雙向鏈表要比單鏈表佔用更多的記憶體空間。
但雙向鏈表可以支援雙向遍曆,它可以支援 O(1) 時間複雜度的情況下找到前驅結點,正是這樣的特點,也使雙向鏈表在某些情況下的插入、刪除等操作都要比單鏈表簡單、高效。
雙向迴圈鏈表
把迴圈鏈表和雙向鏈表結合起來,就是雙向迴圈鏈表,如所示:
鏈表和數組各種操作時間複雜度對比
數組簡單易用,在實現上使用的是連續的記憶體空間,可以藉助 CPU 的緩衝機制,預讀數組中的資料,所以訪問效率更高。而鏈表在記憶體中並不是連續儲存,所以對 CPU 緩衝不友好,沒辦法有效預讀,訪問效率較低。
數組的缺點是大小固定,而且需要一塊連續的記憶體空間。相比起來,鏈表則較為靈活,沒有大小限制,天然支援動態擴容。
內容小結
- 鏈表是一種非連續性的線性表資料結構。
- 和數組相比,鏈表更適合插入、刪除操作頻繁的情境。
- 鏈表查詢的時間複雜度較高,不適用於查詢操作頻繁的情境。
鏈表(上)