前言
鏈表(Linked list)比數組稍微復雜一點,在我們生活中用到最常見的應該是緩存,它是一種提高數據讀取性能的技術,常見的如cpu緩存,瀏覽器緩存,數據庫緩存等。今天我們就來學習一下鏈表
正文
一、鏈表的定義?
1.一種線性表(數據排成像一條線一樣的結構。每個線性表上的數據最多有前后兩個方向);
2.從存儲結構來看,通過“指針”,將一組零散的內存塊串聯起來使用的數據結構;
3.鏈表中的每一個內存塊被稱為結點Node,結點除了存儲數據外,還需記錄鏈上下一個節點的地址(next)
二、鏈表的優缺點
1.插入、刪除數據效率高,時間復雜度為O(1)(只需更改指針指向即可),隨機訪問效率低,時間復雜度為O(n)級別(需要從鏈頭至鏈尾進行遍歷)。
2.和數組相比,內存空間消耗更大,因為每個存儲數據的節點都需要額外的空間存儲后繼指針。
三、常用鏈表:單鏈表、循環鏈表、雙向鏈表、雙向循環鏈表和塊狀鏈表
1.單鏈表
1)每個節點只包含一個指針,即后繼指針。
2)單鏈表有兩個特殊的節點,即首節點和尾節點。
用首節點地址表示整條鏈表,尾節點的后繼指針指向空地址null。
3)性能特點:插入和刪除節點的時間復雜度為O(1),查找的時間復雜度為O(n)。
2.循環鏈表
1)除了尾節點的后繼指針指向首節點的地址外均與單鏈表一致。
2)適用於存儲有循環特點的數據,比如約瑟夫問題。
3.雙向鏈表
1)節點除了存儲數據外,還有兩個指針分別指向前一個節點地址(前驅指針prev)和下一個節點地址(后繼指針next)。
2)當此“連接”為第一個“連接”時,指向空值或者空列表
當此“連接”為最后一個“連接”時,指向空值或者空列表)
3)性能特點:
和單鏈表相比,存儲相同的數據,需要消耗更多的存儲空間。
插入、刪除操作比單鏈表效率更高O(1)級別。
以刪除操作為例,刪除操作分為2種情況:
給定數據值刪除對應節點和給定節點地址刪除節點。
對於前一種情況,單鏈表和雙向鏈表都需要從頭到尾進行遍歷從而找到對應節點進行刪除,時間復雜度為O(n)。
對於第二種情況,要進行刪除操作必須找到前驅節點,單鏈表需要從頭到尾進行遍歷直到p->next = q,時間復雜度為O(n),而雙向鏈表可以直接找到前驅節點,時間復雜度為O(1)。
對於一個有序鏈表,雙向鏈表的按值查詢效率要比單鏈表高一些。
因為我們可以記錄上次查找的位置p,每一次查詢時,根據要查找的值與p的大小關系,決定是往前還是往后查找,所以平均只需要查找一半的數據。
4.雙向循環鏈表(雙向,循環鏈表的結合)
首節點的前驅指針指向尾節點,尾節點的后繼指針指向首節點。
5.塊狀鏈表
塊狀鏈表本身是一個鏈表,但是鏈表儲存的並不是一般的數據,而是由這些數據組成的順序表。每一個塊狀鏈表的節點,也就是順序表,可以被叫做一個塊。
塊狀鏈表通過使用可變的順序表的長度和特殊的插入、刪除方式,可以在達到{\displaystyle O({\sqrt {n}})}的復雜度。塊狀鏈表另一個特點是相對於普通鏈表來說節省內存,因為不用保存指向每一個數據節點的指針。
四、數組VS鏈表
1.插入、刪除和隨機訪問的時間復雜度
數組:插入、刪除的時間復雜度是O(n),隨機訪問的時間復雜度是O(1)。
鏈表:插入、刪除的時間復雜度是O(1),隨機訪問的時間復雜端是O(n)。
2.數組缺點
1)若申請內存空間很大,比如100M,但若內存空間沒有100M的連續空間時,則會申請失敗,盡管內存可用空間超過100M。
2)大小固定,若存儲空間不足,需進行擴容,一旦擴容就要進行數據復制,而這時非常費時的。
3.鏈表缺點
1)內存空間消耗更大,因為需要額外的空間存儲指針信息。
2)對鏈表進行頻繁的插入和刪除操作,會導致頻繁的內存申請和釋放,容易造成內存碎片,如果是Java語言,還可能會造成頻繁的GC(自動垃圾回收器)操作。
4.如何選擇
數組簡單易用,在實現上使用連續的內存空間,可以借助CPU的緩沖機制預讀數組中的數據,所以訪問效率更高,而鏈表在內存中並不是連續存儲,所以對CPU緩存不友好,沒辦法預讀。
如果代碼對內存的使用非常苛刻,那數組就更適合
CPU緩存機制指的是什么?為什么就數組更好了?
CPU在從內存讀取數據的時候,會先把讀取到的數據加載到CPU的緩存中。而CPU每次從內存讀取數據並不是只讀取那個特定要訪問的地址,而是讀取一個數據塊(這個大小我不太確定。。)並保存到CPU緩存中,然后下次訪問內存數據的時候就會先從CPU緩存開始查找,如果找到就不需要再從內存中取。這樣就實現了比內存訪問速度更快的機制,也就是CPU緩存存在的意義:為了彌補內存訪問速度過慢與CPU執行速度快之間的差異而引入。
對於數組來說,存儲空間是連續的,所以在加載某個下標的時候可以把以后的幾個下標元素也加載到CPU緩存這樣執行速度會快於存儲空間不連續的鏈表存儲。
相關文章
以上內容為個人的學習筆記,僅作為學習交流之用。
歡迎大家關注公眾號,不定時干貨,只做有價值的輸出
作者:Dawnzhang
出處:https://www.cnblogs.com/clwydjgs/p/9778394.html
版權:本文版權歸作者
轉載:歡迎轉載,但未經作者同意,必須保留此段聲明;必須在文章中給出原文連接;否則必究法律責任