鏈表(圖文詳解)

鏈表的概念

  鏈表是一種物理存儲結構上非連續,非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。
在這裏插入圖片描述
  鏈表的結構是多式多樣的,當時通常用的也就是兩種:
在這裏插入圖片描述
在這裏插入圖片描述
  無頭單向非循環列表:結構簡單,一般不會單獨用來存放數據。實際中更多是作爲其他數據結構的子結構,比如說哈希桶等等。
  帶頭雙向循環鏈表:結構最複雜,一般單獨存儲數據。實際中經常使用的鏈表數據結構,都是帶頭雙向循環鏈表。這個結構雖然複雜,但是使用代碼實現後會發現這個結構會帶來很多優勢,實現反而簡單了。

鏈表和數組的區別:

兩者的區別:

  1. 數組靜態分配內存,鏈表動態分配內存。
  2. 數組在內存中是連續的,鏈表是不連續的。
  3. 數組利用下標定位,查找的時間複雜度是O(1),鏈表通過遍歷定位元素,查找的時間複雜度是O(N)。
  4. 數組插入和刪除需要移動其他元素,時間複雜度是O(N),鏈表的插入或刪除不需要移動其他元素,時間複雜度是O(1)。
數組的優點
  1. 隨機訪問性比較強,可以通過下標進行快速定位。
  2. 查找速度快
數組的缺點
  1. 插入和刪除的效率低,需要移動其他元素。
  2. 會造成內存的浪費,因爲內存是連續的,所以在申請數組的時候就必須規定七內存的大小,如果不合適,就會造成內存的浪費。
  3. 內存空間要求高,創建一個數組,必須要有足夠的連續內存空間。
  4. 數組的大小是固定的,在創建數組的時候就已經規定好,不能動態拓展。
鏈表的優點
  1. 插入和刪除的效率高,只需要改變指針的指向就可以進行插入和刪除。
  2. 內存利用率高,不會浪費內存,可以使用內存中細小的不連續的空間,只有在需要的時候纔去創建空間。大小不固定,拓展很靈活。
鏈表的缺點

查找的效率低,因爲鏈表是從第一個節點向後遍歷查找。

單鏈表和雙鏈表的區別:

在這裏插入圖片描述

  1. 單鏈表的每一個節點中只有指向下一個結點的指針,不能進行回溯,適用於節點的增加和刪除。
  2. 雙鏈表的每一個節點給中既有指向下一個結點的指針,也有指向上一個結點的指針,可以快速的找到當前節點的前一個節點,適用於需要雙向查找節點值的情況。
雙鏈表相對於單鏈表的優點:

  刪除單鏈表中的某個節點時,一定要得到待刪除節點的前驅,得到其前驅的方法一般是在定位待刪除節點的時候一路保存當前節點的前驅,這樣指針的總的的移動操作爲2n次,如果是用雙鏈表,就不需要去定位前驅,所以指針的總的的移動操作爲n次。
  查找時也是一樣的,可以用二分法的思路,從頭節點向後和尾節點向前同時進行,這樣效率也可以提高一倍,但是爲什麼市場上對於單鏈表的使用要超過雙鏈表呢?從存儲結構來看,每一個雙鏈表的節點都比單鏈表的節點多一個指針,如果長度是n,就需要n*lenght(32位是4字節,64位是8字節)的空間,這在一些追求時間效率不高的應用下就不適用了,因爲他佔的空間大於單鏈表的1/3,所以設計者就會一時間換空間。

鏈表環問題

判斷是否有環

  定義一個快指針和一個慢指針,快指針一次走兩步,慢指針一次走兩步,會出現兩種情況,情況一指針走到了空的位置,那就說明這個鏈表不帶環。情況二兩個指針相遇,說明這個鏈表帶環。

獲得入環節點

  如果不考慮空間複雜度,可以使用一個map來記錄走過的節點,這個指針一直向後遍歷如果遇到空,說明這個鏈表不帶環,也就沒有入環節點,如果沒有遇到空,如果遇到第一個在map中存在的節點,就說明回到了出發點,這個節點就是環的入口節點。如果不建立額外的空間,先使用快慢指針判斷這個鏈表是否有環,如果有環將相遇節點記錄,然後一個指針從鏈表的起始位置開始一次走一步,另一個指針從記錄的節點開始一次走一步,當兩個節點再次相遇,這個相遇節點就是環的入口節點。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章