程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 數據結構與算法之鏈表

數據結構與算法之鏈表

編輯:關於C++

鏈表的分類:

(1)單鏈表

頭插法:只需要維護一個頭結點即可,常用來模擬堆棧;

尾插法:需要維護頭結點和尾結點,常用來模擬隊列。

(2)雙向鏈表

雙向遍歷,可以用來保存網頁的歷史記錄等;

(3)循環鏈表

經常出現在面試題中,判斷鏈表是否有環。

鏈表的刪除

方式一:維護兩個指針,current(表示當前節點)和previous(表示當前節點的前一個節點)。當current遍歷到要刪除的元素時,執行previous->next = current->next,並刪除current。在刪除時,需要判斷current是否等於head節點。

方式二:維護一個二級指針,Node ** current和一個臨時變量entry。刪除時只需要執行*current = entry -> next. 並刪除entry即可,無需判斷是否為head節點。

基於內存池的鏈表

傳統鏈表的缺點:鏈表在插入過程中會調用系統函數分配內存,然後將該塊內存鏈接到鏈表中。插入操作有三個缺點:

(1)進行頻繁的系統調用,會浪費不少時間;

(2)在鏈表節點分配釋放的過程中會產生很多內存碎片,不利於分配整塊內存;

(3)可能會導致頻繁的cache缺失;

解決方案:

構造一個內存池,每次插入都從內存池中獲取一個節點,每次刪除都將節點放回內存池。這樣做的優點是不存在內存碎片,也不進行系統調用。

鏈表的反轉(面試常考)

(1)思路一:在從前往後遍歷的過程中進行反轉。維護三個指針,分別指向當前節點以及當前節點的前後節點。

(2)思路二:將第三個節點到第N個節點,依次逐節點插入到第一個節點(head節點)之後,最後將第一個節點挪到新表的表尾。

(3)思路三:遞歸的處理head後面的節點,然後再修改head和head後面節點的指向。

倒序打印鏈表

(1)遞歸:倒序打印意味著先最後的元素,然後依次往前打印,可以用遞歸實現這個過程。遞歸的打印head後面所有的節點,然後打印head節點。

(2)棧模擬:遞歸使用系統棧(活動記錄),我們可以用STL中的棧來模擬上述遞歸過程。首先順序遍歷一遍鏈表,將元素放入堆棧,然後依次出棧打印元素。

判斷鏈表是否有環

(1)如何判斷是否存在環?

解法:設置一對快慢指針,同時從鏈表的頭開始往前遍歷。慢指針一次前進一步,快指針一次前進兩步,如果有環則兩個指針會相遇。

(2)如何知道環的長度?

解法:記錄下問題(1)的碰撞點,快慢指針再從該位置遍歷一遍環。下次碰撞慢指針走過的距離就是環的長度。

(3)如何找出環的連接點在哪裡?

解法:碰撞點到連接點的距離 = 頭指針到連接點的距離,再次從兩點遍歷即可。

(4)帶環鏈表的長度是多少?

解法:問題2+問題3.

間接尋址的基本概念

間接尋址簡單描述就是二級指針的應用。二級指針有三個含義:指向指針的指針、一維數組、二維數組。間接尋址在此特指其一維數組的含義。

間接尋址是數組和鏈表的組合。既保留了數組的許多優點,又獲得了鏈表的重要特色。首先,可以根據索引在O(1)的時間內訪問每個元素。其次,可以采用二分在對數時間內對一個有序表進行搜索。最後,在諸如插入和刪除操作期間不必對元素進行實際的移動。間接尋址使用指針數組來跟蹤每一個元素,對元素本身如何分配不設限制(可離散可連續)。

間接尋址的應用

(1)內存池

自構建等塊內存池,每一個指針分別指向每一塊內存的首地址。內存池可以避免內存碎片和系統調用。

(2)散列鏈表

如果指針指向的元素包含next指針,則間接尋址變成了散列鏈表。

模擬指針的基本概念

模擬指針簡單描述就是利用數組的下標當指針。模擬指針的最大用途是解決並查集問題。

(1)實現一:首先構造一個節點數組,節點包含兩個域:data和link。link域指向數組中的其他節點。和間接尋址有相似之處。

(2)實現二:數組只包含link域,可以用來模擬樹。

等價類的定義

定義:假定有一個具有n個元素的集合U,另有一個具有r個關系的集合R。如果(a,b)屬於R,則元素a和b是等價的。等價類是指相互等價元素的最大集合。換句話說,將集合U根據關系進行劃分,類內的元素等價,可以看做是一種聚類。

離線等價類:已知n和R,確定所有的等價類。

在線等價類:初始時有n個元素,每個元素都屬於一個獨立的等價類。然後不停的執行Find和Union操作向R中添加新關系。通常被稱為並查集問題。

並查集的基本概念

並查集的操作:

(1)Find:查詢元素a和b是否屬於同一類;

(2)Union:合並元素a和b所在的類。

並查集的實現:

采用方式二的模擬指針。數組的下標即表示指針,指針的指向使並查集構成了一棵虛擬的森林。但是並查集不關注每棵樹的形狀以及相互指向關系,只關注最終的根節點以及該樹的元素個數或者高度。

並查集的優化:

可以根據重量規則或者高度規則對並查集的操作進行優化。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved