7、鏈表(下):如何輕松寫出正確的鏈表代碼?
很汗顏,現在讓自己完整的寫出一個簡單的鏈表結構竟然會無法動筆,作為一個程序猿,需要修行的路還很長。
技巧一:理解指針或引用的含義
將某個變量賦值給指針,實際上就是將這個變量的地址賦值給指針,或者反過來說,指針中存儲了這個變量的內存地址,指向了這個變量,通過指針就能找到這個變量。
例子: p->next = q。這行代碼的意思是p節點的next指針存儲了q節點的內存地址。
同理, p->next = p->next->next。這行代碼的意思是p節點的next指針存儲了p節點的下下一個節點的地址。
技巧二:警惕指針丟失和內存泄漏
舉例插入節點:
如圖所示,我們希望在節點a和b之間插入節點x,假設當前指針p指向節點a。如果代碼如下就會發生指針丟失和內存泄漏。
p->next = x;
x->next = p->next;
此處在p->next執行之後,其指針就不再指向b了,而是指向x。第二行代碼就相當於自己指向了自己。因此,鏈表斷成了兩半,從節點b往後的所有界定啊都無法訪問。
正確方式:將第一行代碼和第二行代碼顛倒順序,就ok了。
技巧三:利用哨兵簡化實現難度
如下,節點p之後插入節點的正確代碼。
x->next = p->next;
p->next = x;
註意:當需要向一個空鏈表中插入第一個節點,上面的邏輯就不能用了。正確答案如下:
if(head==null){ head = new_node; }
同理,在編寫鏈表的刪除操作之時,分為兩種情況:
第一種,刪除節點不是尾節點,而是p節點的後繼結點
p->next = p->next->next;
第二種,刪除結點是尾結點
if(node->next == null){ head = null; }
技巧四:重點留意邊界條件處理
如果鏈表為空,代碼能否正常工作?
如果鏈表只包含一個結點時,代碼是否能正常工作?
如果鏈表只包含兩個結點時,代碼是否能正常工作?
代碼邏輯在處理頭結點和尾節點的時候,是否能正常工作?
技巧五:自己畫圖,輔助記憶
常見的鏈表操作:
一、單鏈表反轉
二、鏈表中環的檢測
三、兩個有序的鏈表的合並
四、刪除鏈表倒數第n個結點
五、求鏈表的中間結點
分別對應LeetCode練習題編號:206,141,21,19,876。
課後思考:你是否能想到其他場景,利用哨兵可以大大簡化編碼難度?
後續把自己實現的五種鏈表操作傳上來。歡迎指正!
7、鏈表(下):如何輕松寫出正確的鏈表代碼?