数据结构二——链表
文章出處:極客時間《數據結構和算法之美》-作者:王爭。該系列文章是本人的學習筆記。
底層存儲
數組:一塊連續的內存空間。
鏈表:用指針串起來的一組零散的內存空間。
鏈表分類:單鏈表、雙向鏈表、循環鏈表
單鏈表
內存塊是連接的節點。每個節點存儲數據和指向下一個節點的指針。第一個節點叫做頭結點,最后一個節點叫做尾節點。尾節點的next=null。
操作特點
1 插入、刪除很快,O(1)。
2 想要隨機訪問只能從頭節點開始遍歷,數到第k個節點。平均時間復雜度O(n)。想象隊列就是一個排隊的隊伍。每個人只知道自己后面的那個人。
循環鏈表
結構特點:循環列表的尾節點指向鏈表的頭結點。
用途:用于解決數據具有環形結構的問題。例如約瑟夫問題。
雙向鏈表
雙向鏈表的節點存儲:數據+指向下一個節點的指針+指向上一個節點的指針。
用途1:更方便的插入刪除
刪除的使用場景一般為:給定一個值,將具有這個值得節點刪除。只是刪除需要O(1)的時間,但是查詢的平均時間復雜度為O(n)。根據時間復雜度的加法原則,時間復雜度為O(n)。
另外一個場景是:已經給定一個節點,刪除這個節點。單項鏈表因為沒有向前的指針,所以需要從頭開始遍歷,找到要刪除節點的前一個節點。平均時間復雜度(O(n))。如果是雙向列表,因為有向前的指針,O(1)就可以實現。
在某個節點前插入一個元素,雙向列表顯示出了優勢,因為有前向指針。時間為O(1)。
用途2:在有序列表中查找更方便
因為每次查詢時,都要比較當前元素和要找元素的大小,然后決定向前走,還是向后走。
鏈表 VS 數組
在時間復雜度方面:
數組:插入、刪除 O(n) ;隨機訪問O(1)
鏈表:插入、刪除O(1);隨機訪問 O(n)
數組的優點:數組更簡單,可以利用CPU緩存,速度更快。
數組的缺點:需要申請固定大小的空間,在擴容的時候更加浪費內存,可能產生OOM。
鏈表的優點:大小可以是不固定的。
鏈表的缺點:內存塊是不連續的,不能利用CPU緩存。
思考題:如何基于鏈表給出LRU緩存
LRU緩存:是指刪除最近訪問少的元素 的緩存策略。
已經訪問過的元素用鏈表存儲。現在假設訪問元素a,有如下情況:
1 a在鏈表中,那把a元素刪除,插入在隊列頭部作為頭結點。
2 a不在鏈表中
2.1 并且鏈表空間充足,則把a插入在鏈表頭部。
2.2 并且鏈表空間不足,則把尾元素刪除,把a插入在鏈表頭部。
因為要遍歷每個元素,所以平均時間復雜度是O(n)。如果使用散列表就能提高速度。
寫好鏈表代碼的幾個技巧
1 理解指針的含義。將某個變量賦值給指針,實際上就是將這個變量的地址賦值給指針。
2 警惕指針丟失和內存泄漏
3 利用啞結點簡化代碼
4 留意邊界條件的處理。鏈表可以考慮的幾個邊界條件有:
4.1 如果列表為空,代碼可以正常運行嗎?
4.2 如果列表只包含一個節點,代碼可以正常運行嗎?
4.2 如果列表含2個節點,代碼可以正常運行嗎?
4.3 代碼邏輯在處理頭、尾節點的時候,代碼可以正常運行嗎?
5 舉例畫圖幫助思考
6 多寫多練
關于鏈表面試中經常遇到的場景
1 單鏈表翻轉
2 是否有環檢測
3 2個有序鏈表合并
4 刪除倒數第k個節點
5 求中間節點
總結
- 上一篇: 模糊综合评价模型 ——确定隶属度
- 下一篇: 京东支付功能流程