鍊錶的分類
迴圈鍊錶
雙向鍊錶演算法:
結構記憶體塊(鍊錶的結點)+後繼指標next(指向下乙個結點);
頭結點鍊錶中第乙個結點,其記錄鍊錶中的基位址;
尾結點鍊錶中的最後乙個結點,其next指標指向null;
時間複雜度
刪除和插入:都只需要改變相鄰結點的next指標指向即可,時間複雜度為o(1);
隨機訪問:不能直接訪問到第k個位置,只能通過頭結點乙個乙個的查詢,所以時間複雜度為o(n);
定義迴圈鍊錶:就是單鏈表的尾結點指標指向了頭結點
直接輸入1次#,並按下space後,將生成1級標題。
輸入2次#,並按下space後,將生成2級標題。
以此類推,我們支援6級標題。有助於使用toc
語法後生成乙個完美的目錄。
/*針對有頭結點的鍊錶
通過快慢指標
快指標每次前進兩個結點,慢指標每次前進乙個結點,快指標的移動速度時慢指標的2倍,快指標在結尾時,慢結點就剛好在中間;
還需考慮鍊錶結點個數奇偶的問題:當快指標移動x次到達末尾時,結點偶數個(有頭結點)或者奇數個(無頭結點),慢指標就指向鍊錶的中點;
當快指標到達倒數第二個位置時,表明結點為奇數個(有頭結點)或者節點為偶數個(無頭結點),根據規則返回上中位數或下中位數或二者之和的一半
*/
char
getmid
(node*
const head)
}}
/*通過快慢指標來實現,快慢指標之間相隔k-1個距離,當快指標到達鍊錶結尾時,慢指標剛好指向鍊錶的k處結點
也就是說:快指標向前走k-1步時,慢指標不動;當快指標走第k步時,慢指標向前移動一步;
**層面:快指標走到第k-2個結點時,慢指標不動;快指標走到第k-1個結點時,慢指標向前移動;隨後快慢指標都迴圈向前移動
乙個結點單位,當快指標到達尾結點時,慢指標就指向了第k處的結點
*/
node*
rgetkthnode
(node*
const head,
int k)
while
(fast-
>pnext !=
null
)//條件不符合,代表fast到達尾結點,此時slow就指向k位置的結點
return slow;
}
參考1
參考2
題目:給定乙個鍊錶,返回鍊錶開始入環的第乙個節點。 如果鍊錶無環,則返回 null。如何獲取入口
入口點為中間結點
我們假設鍊錶的起始點到環的入口點的距離為l,環的周長為r,環的入口點到快慢指標的相遇位置的距離為x(圖中紅色箭頭標註的就是快慢指標的相遇點)。
快指標走的距離:f = l+x+nr慢指標走的距離:s = l+x
因為快指標走的距離是慢指標的兩倍,所以f = 2s。
l+x+nr = 2 * (l + x)
l = nr - x
當n = 1時,也就是快指標走了一圈之後,在第二圈的時候遇見了慢指標,l = r - x也就是,當鍊表指標乙個指向頭結點,乙個指向相遇點,二者分別迴圈前進乙個單位,直到二者相遇即可找到入口點。
//此時fast和slow都代表著相遇點
//相遇點就是頭結點時,直接返回
if(head != slow)
//入口點不是鍊錶的頭結點時,找到相遇點
}return slow;
}
題目:判斷兩個鍊錶是否相交。分解:判斷兩個鍊錶是否相交。思路:遍歷兩個鍊錶得到二者的長度,將指標指向長鍊表的a點,使得a點到尾點的長度與短鍊錶長度一致,同時移動長短鍊錶,若二者的指標指向同乙個位置,則說明二者相交
bool
isintersection
(node*
const head1, node*
const head2)
return
true
;}
分解:使用三個指標,乙個指標指向反轉後的鍊錶,另外兩個指標用於移動和取鍊錶的結點。資料結構與演算法 鍊錶
題目 合併兩個已經排序好的鍊錶 非遞迴和遞迴兩種 方法1 cpp view plain copy print color 000000 合併鍊錶.cpp 定義控制台應用程式的入口點。include stdafx.h include using namespace std struct listnod...
資料結構與演算法 鍊錶
在講述鍊錶之前讓我們對資料結構進行乙個簡單的回顧 我們知道,資料結構指的是描述實際問題中各個資料項節點之間的前後邏輯結構關係,即要麼是線性結構 即某一資料項的前繼節點和後繼節點有且只有乙個 要麼是非線性結構 即某一資料節點的前驅或者後繼節點不止乙個 在確定了實際資料項的資料結構之後,我們要採用某種儲...
資料結構與演算法 鍊錶
反轉鍊錶 def reverse head q none p heap while p temp p.next p.next q q pp temp return p判斷鍊錶環 def meetingnode head if not head return slow head fast head.n...