1. 程式人生 > >10年架構師圖解單鏈表,一篇圖文徹底搞懂

10年架構師圖解單鏈表,一篇圖文徹底搞懂

§單鏈表的定義


每一個節點都有一個向後的指標(
引用)指向下一個節點,最後一個節點指向NULL表示結束,有一個Head()指標指向第一個節點表示開始。如下圖:



§單鏈表的特點


耗子戴眼鏡,鼠目寸光
我們只能拿到頭節點,(
在不逐個遍歷的情況下),後面還有多少個節點,它們是什麼,它們在哪裡,誰是最後一個節點?這些我們統統都無法知道。

肉包子打狗,有去無回
遍歷時只能從前往後,
是單向的,一旦錯過某個節點,只能從頭再遍歷一次,確保這次不要錯過。

§節點的增/刪/交換


增加節點
此時必須有兩個指標,一個指向插入位置
的那個節點,稱它為prev

指標,一個指向待插入的節點,稱它為node指標。如下圖:


插入過程相等於連結的斷開與重建。如下圖:

用程式碼表示:
node.next = prev.next
prev.next = node


刪除節點
此時最好有兩個指標,一個指向待刪除節點前的那個節點,稱它為prev指標,一個指向待刪除節點,稱它為node指標。如下圖:

用程式碼表示:
node = prev.next
prev.next = node.next
node.next = NULL


交換節點
此時必須有兩個指標,一個指向待交換的兩個節點前的那個節點,稱它為prev指標,一個指向待交換的兩個節點中的第一個節點,稱它為first指標。如下圖:

用程式碼表示:
first = prev.next
prev.next = first.next
first.next = prev.next.next
prev.next.next = first


§逆序


將連結串列的順序倒過來。有兩種方法:依次交換法集體向後轉法

依次交換法
1先和2交換,再和3交換,再和4交換,再和5交換,現在1已經在最後了,2是第一個。如下圖:


2先和3交換,再和4交換,再和5交換,此時2已經是倒數第二個了,3是第一個。如下圖:


依次類推,用3進行一輪交換,再用4進行一輪交換,逆序就完成了。如下圖:

感覺和氣泡排序法有些神似


集體向後轉法
這種方法的思路來自於
體育課一排縱隊和體育老師面對面站著。老師就是頭節點,縱隊就是單鏈表。

縱隊集體向後轉,老師再走過去和新縱隊面對面
單鏈表換了方向,頭節點換了指向

需要三個指標,一個指向
已經向後轉過的部分,稱為done指標;一個指向正要向後轉的那個節點,稱為doing指標;一個指向剩餘待向後轉的部分,稱為todo指標。

一開始
還沒有一個向後轉的,因此done = NULL,doing指向第一個,即doing = head,todo指向第二個,即todo = doing.next。如下圖:


讓正在向後轉的節點(即doing)的next指標指向已經向後轉過的(即done);done,doing,todo三個指標分別向右移動一個節點。如下圖是操作過程操作後的結果


用程式碼表示:
doing.next = done
done = doing
doing = todo
(如果doing是NULL,結束)
todo = todo.next(如果next是NULL,則賦NULL)


同理,進行一步,如下圖:



同理,最後一步,結束後即完成逆序。如下圖:



兩種方法的比較,一是連結串列的方向不變變換節點位置;二是節點位置不變變換連結串列的方向

§LeetCode,以K個節點為一組逆序

這是leetcode中linkedlist部分的一道題,級別是hard。

如果k=3,每3個節點逆序一下,直到結尾,如果最後剩餘的節點不夠3個,則原樣保留。

第一步,0、1、2逆序



第二步,3、4、5逆序



第三步,6、7、8逆序



第四步,9原樣保留



要求:只能定義常量個數的額外變數(或者說只能使用額外常量的記憶體)。

PS:這道題目雖然是hard級別,但是有了以上的講解,相信大多數人都能做出來。注意邊界條件和細心即可。

相關文章

小學生都能看懂的表示式計算(圖解)

五分鐘輕鬆瞭解Hbase列式儲存(圖解)




(完)


程式設計新說


用獨特的視角說技術