鍊錶的總結

2021-10-10 00:18:41 字數 1563 閱讀 2966

優雅的寫出鍊錶**(6大學習技巧)

2020.9.22

一、理解指標或引用的含義

示例:p -> next = q;表示p節點的後繼指標儲存了q節點的記憶體位址。

p -> next = p -> next ->next;表示p節點的後繼指標儲存了p節點的下下個節點的記憶體位址。

二、警惕指標丟失和記憶體洩漏(單鏈表)

插入節點

在節點a和節點b之間插入節點x,b是a的下一節點,p指標指向節點a,則造成指標丟失和記憶體洩漏的**:

p—>next = x;

x—>next = p—>next;

顯然這會導致x節點的後繼指標指向自身。

正確的寫法是這兩句**交換順序,即:

x—>next = p—>next;

p—>next = x;

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

什麼是「哨兵」?

鍊錶中的「哨兵」節點是解決邊界問題的,不參與業務邏輯。如果我們引入「哨兵」節點,則不管鍊錶是否為空。head指標都會指向這個「哨兵」節點。我們把這種有「哨兵」節點的鍊錶稱為帶頭鍊錶,相反,沒有「哨兵」節點的鍊錶就成為不帶頭鍊錶。

未引入「哨兵」的情況

如果在p節點後插入乙個節點,只需2行**即可搞定:

new_node—>next = p—>next;

p—>next = new_node;

但,若向空煉表中插入乙個節點,則**如下:

if(head == null)
如果要刪除節點p的後繼節點,只需1行**即可搞定:

p—>next = p—>next—>next;

但,若是刪除鍊錶的最有乙個節點(鍊錶中只剩下這個節點),則**如下:

if(head—>next == null)
從上面的情況可以看出,針對鍊錶的插入、刪除操作,需要對插入第乙個節點和刪除最後乙個節點的情況進行特殊處理。這樣**就會顯得很繁瑣,所以引入「哨兵」節點來解決這個問題。

引入「哨兵」的情況

「哨兵」節點不儲存資料,無論鍊錶是否為空,head指標都會指向它,作為鍊錶的頭結點始終存在。這樣,插入第乙個節點和插入其他節點,刪除最後乙個節點和刪除其他節點都可以統一為相同的**實現邏輯了。

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

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

經常用來檢查鍊錶是否正確的邊界4個邊界條件:

1.如果鍊錶為空時,**是否能正常工作?

2.如果鍊錶只包含乙個節點時,**是否能正常工作?

3.如果鍊錶只包含兩個節點時,**是否能正常工作?

4.**邏輯在處理頭尾節點時是否能正常工作?

五、舉例畫圖,輔助思考

六、多寫多練,沒有捷徑

節點的定義:

typedef struct singlylinkednode  singlylinkednode;
5個常見的鍊錶操作:

1.單鏈表反轉

2.鍊錶中環的檢測

3.兩個有序鍊錶合併

4.刪除鍊錶倒數第n個節點

5.求鍊錶的中間節點

鍊錶 鍊錶環問題總結

給定乙個單鏈表,只給出頭指標h 1 如何判斷是否存在環?2 如何知道環的長度?3 如何找出環的連線點在 4 帶環鍊錶的長度是多少?1 如何判斷是否存在環?對於問題1,使用追趕的方法,設定兩個指標slow fast,從頭指標開始,每次分別前進1步 2步。如存在環,則兩者相遇 如不存在環,fast遇到n...

靜態鍊錶的總結

1.靜態鍊錶的定義 用陣列描述的鍊錶就叫做靜態鍊錶 2.為什麼有靜態鍊錶 因為有些高階語言沒有向c語言的指標,有人想出來用陣列來代替指標,來描述單鏈表。3.怎樣定義靜態鍊錶 typedef struct componet,staticlinklist maxsize 靜態鍊錶最基本的兩部分就是 第一...

l鍊錶的總結

就快要參加考核了,總結一下學的鍊錶內容,加深記憶,啊啊啊,為什麼考核呢,我還是個寶寶。靜態鍊錶 把線性表的元素存放在陣列中,這些元素通過邏輯關係來進行連線。陣列單元存放鍊錶結點,結點的鏈域 鏈就是代表指標,是下一元素的位址,鍊錶中乙個結點可以分為兩個部分,乙個指標域用來存放指標,另乙個資料域用來存放...