對於單鏈表講,單鏈表中的結點不一定儲存在相鄰位置,乙個結點儲存兩個資訊,一是該節點的值,二是指向下乙個結點的位置資訊。
// 單鏈表節點的結構
public
class
listnode
}
本文的主要目的是以單鏈表出發,遞迴實現反轉單鏈表——>反轉鍊錶前n個結點——>反轉鍊錶的一部分
這個演算法可能很多讀者都聽說過,這裡詳細介紹一下,先直接看實現**:
listnode reverse
(listnode head)
下面來詳細解釋一下這段**。
首先(大體出現鍊錶反轉的結果):
對於遞迴演算法,最重要的就是明確遞迴函式的定義。具體來說,我們的reverse函式定義是這樣的:
輸入乙個節點head,將「以head為起點」的鍊錶反轉,並返回反轉之後的頭結點。
明白了函式的定義,再來看這個問題。比如說我們想反轉這個鍊錶:
那麼輸入reverse(head)後,會在這裡進行遞迴:
listnode last = reverse(head.next);
不要跳進遞迴(你的腦袋能壓幾個棧呀?),而是要根據剛才的函式定義,來弄清楚這段**會產生什麼結果:
按照定義,這個reverse(head.next)執行完成後,整個鍊錶應該變成了這樣:
並且根據函式定義,reverse函式會返回反轉之後的頭結點,我們用變數last接收了。
然後(指標進行修正上下結點):
現在再來看下面的**:
head.next.next = head; //修正上結點——將head的位址賦予元素2的位址(即鍊錶2後面指向1)
接下來進行的操作:
head.next = null; // 修正下結點
最後(遞迴結束邊界base case):
if (head.next == null) return head;
**小小總結下
大體可以分為以下三步驟:
對於遞迴問題,我們一定要知道遞迴的定義(遞迴後長怎麼樣的?)
對於遞迴後的鍊錶修改上下結點的(位置)指向
明白遞迴的終止條件(basecase)——結點指向下乙個位置為null
理解了這兩點後,我們就可以進一步深入了,接下來的問題其實都是在這個演算法上的擴充套件。
首先看下大概的過程:
**實現如下:
listnode tem = null;
// 後驅結點(用來修改——反轉後中 返回結點的指向!)
listnode reserven
(listnode head,
int n)
// 以 head.next 為起點,需要反轉前 n - 1 個節點
listnode last =
reseven
(head.next, n-1)
; head.next.next = head;
// 讓反轉之後的 head 節點和後面的節點連起來
head.next = tem;
return last;
}
小小總結下反轉鍊錶前n個結點對比第乙個反轉鍊錶,大體的思路差不多,都是
定義遞迴方程(明白遞迴反戰後是長怎麼樣的?)
對於遞迴後的鍊錶修改上下結點的(位置)指向
明白遞迴的終止條件(basecase)——結點指向下乙個位置為null
但是相比較第乙個,這裡重點關注結束條件——n,和返回結點的指向(第乙個是指向null,這個是指向第n個結點的下乙個)
問題:給乙個索引區間[m,n](索引從 1 開始),僅僅反轉區間中的鍊錶元素。
listnode reversebetween
(listnode head,
int m,
int n)
// 前僅到反轉的起點觸發 base case
head.next =
reversebetween
(head.next, m-
1, n-1)
;return head;
}
核心關注點是:邊界狀態呼叫鍊錶中的前n個結點
遞迴強調三步驟:
定義遞迴方程(遞迴後長怎麼樣的?)
遞迴直接呼叫返回(腦子別壓棧!)
明白遞迴終止條件(basecase)
參考:
分析讓複雜問題簡單 複雜鍊錶的複製
輸入乙個複雜鍊錶 每個節點中有節點值,以及兩個指標,乙個指向下乙個節點,另乙個特殊指標指向任意乙個節點 返回結果為複製後複雜鍊錶的head。注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空 思路 1,如果鍊錶為空鍊錶,則返回本身即可。2,如果鍊錶非空的情況 如果沒有特殊指標,則只...
(複雜問題分步驟)劍指 複雜鍊錶的複製
輸入乙個複雜鍊錶 每個節點中有節點值,以及兩個指標,乙個指向下乙個節點,另乙個特殊指標指向任意乙個節點 返回結果為複製後複雜鍊錶的head。注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空 占用記憶體 9400k public class randomlistnode publi...
35 複雜鍊錶的複製( 分解讓複雜問題簡單)
題目描述 輸入乙個複雜鍊錶 每個節點中有節點值,以及兩個指標,乙個指向下乙個節點,另乙個特殊指標指向任意乙個節點 返回結果為複製後複雜鍊錶的head。注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空 測試用例 功能測試 節點中的random指向自身 兩個節點的random形成環狀...