數據結構與算法學習筆記之寫鏈表代碼的正確姿式(下)

前言

想成功你就得有決心,並有方法和技巧的付出精力。html

正文

如何優雅的寫出鏈表代碼?

 

1、理解指針或引用的含義

1.含義:

將某個變量(對象)賦值給指針(引用),實際上就是就是將這個變量(對象)的地址賦值給指針(引用)。node

指針中存儲了這個變量的內存地址,指向了這個變量,經過指針就能找到這個變量算法

 

2.示例

p—>next = q; 表示p節點的後繼指針存儲了q節點的內存地址。
p—>next = p—>next—>next; 表示p節點的後繼指針存儲了p節點的下下個節點的內存地址。數組

 

2、警戒指針丟失和內存泄漏(單鏈表)

在插入和刪除結點時,要注意先持有後面的結點再操做,否者一旦後面結點的前繼指針被斷開,就沒法再訪問,致使內存泄漏。數據結構

1.插入節點

在節點a和節點b之間插入節點x,b是a的下一節點,,p指針指向節點a,則形成指針丟失和內存泄漏的代碼:p—>next = x;x—>next = p—>next; 顯然這會致使x節點的後繼指針指向自身。
正確的寫法是2句代碼交換順序,即:x—>next = p—>next; p—>next = x;post

 

2.刪除節點


在節點a和節點b之間刪除節點b,b是a的下一節點,p指針指向節點a:p—>next = p—>next—>next性能

 

3、利用「哨兵」簡化實現難度

1.什麼是「哨兵」?


鏈表中的「哨兵」節點是解決邊界問題的,不參與業務邏輯。若是咱們引入「哨兵」節點,則無論鏈表是否爲空,head指針都會指向這個「哨兵」節點。咱們把這種有「哨兵」節點的鏈表稱爲帶頭鏈表,相反,沒有「哨兵」節點的鏈表就稱爲不帶頭鏈表。學習

 

2.未引入「哨兵」的狀況

若是在p節點後插入一個節點,只需2行代碼便可搞定:
new_node—>next = p—>next;
p—>next = new_node;
但,若向空鏈表中插入一個節點,則代碼以下:
if(head == null){
head = new_node;
}
若是要刪除節點p的後繼節點,只需1行代碼便可搞定:
p—>next = p—>next—>next;
但,如果刪除鏈表的最有一個節點(鏈表中只剩下這個節點),則代碼以下:
if(head—>next == null){
head = null;
}
從上面的狀況能夠看出,針對鏈表的插入、刪除操做,須要對插入第一個節點和刪除最後一個節點的狀況進行特殊處理。這樣代碼就會顯得很繁瑣,因此引入「哨兵」節點來解決這個問題。url

 

3.引入「哨兵」的狀況

「哨兵」節點不存儲數據,不管鏈表是否爲空,head指針都會指向它,做爲鏈表的頭結點始終存在。這樣,插入第一個節點和插入其餘節點,刪除最後一個節點和刪除其餘節點均可以統一爲相同的代碼實現邏輯了。spa

 

4.「哨兵」還有哪些應用場景?

這個知識有限,暫時想不出來呀!但總結起來,哨兵最大的做用就是簡化邊界條件的處理。

 

4、重點留意邊界條件處理


常常用來檢查鏈表是否正確的邊界4個邊界條件:
1.若是鏈表爲空時,代碼是否能正常工做?
2.若是鏈表只包含一個節點時,代碼是否能正常工做?
3.若是鏈表只包含兩個節點時,代碼是否能正常工做?
4.代碼邏輯在處理頭尾節點時是否能正常工做?

 

5、舉例畫圖,輔助思考


核心思想:釋放腦容量,留更多的給邏輯思考,這樣就會感受到思路清晰不少。

 

6、多寫多練,沒有捷徑

 

5個常見的鏈表操做:

1.單鏈表反轉
2.鏈表中環的檢測
3.兩個有序鏈表合併
4.刪除鏈表倒數第n個節點
5.求鏈表的中間節點

 

相關文章

數據結構與算法學習筆記之 提升讀取性能的鏈表(上)

數據結構與算法學習筆記之 從0編號的數組

 

以上內容爲我的的學習筆記,僅做爲學習交流之用。

歡迎你們關注公衆號,不定時乾貨,只作有價值的輸出

做者:Dawnzhang 
出處:http://www.javashuo.com/article/p-uozbppkv-eb.html

版權:本文版權歸做者轉載:歡迎轉載,但未經做者贊成,必須保留此段聲明;必須在文章中給出原文鏈接;不然必究法律責任

相關文章
相關標籤/搜索