題目描述
給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指針。
分析
接着前一天的分析工作做的,參考了書籍的分析。今天的分析過程:
使用一個番茄鍾分析得出:
根據中序遍歷的特點,左子樹-根節點-右子樹。既然已經輸出了根節點(即給定的節點),則下一步的輸出存在兩種情況:有無右子樹。
- 無右子樹
根據中序遍歷的特點,不斷向上回溯,判斷當前節點是否爲父節點的右子節點,如果是,代表父節點已經輸出過了,繼續向上回溯,將父節點作爲當前節點繼續判斷。
- 有右子樹
則選出以當前節點的右子節點爲根節點的左子樹的最左端的葉子節點,輸出該節點
複雜度分析
時間複雜度:O(logN) 空間複雜度:O(1)
邊界分析
分析出的邊界條件:空樹,每次求節點的左節點、右節點、父節點時都應該判斷是否存在,因爲這個問題提交了好幾次。
自己寫的代碼
/*
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode)
{
//判斷是否是空子樹
//判斷有無右子樹
if(pNode.right == null){
//回溯判斷該節點是否爲其父節點的右子節點
if(pNode.next == null){
return null;
}
TreeLinkNode fatherNode = pNode.next;
//未考慮這個情況,導致一直過不了
if(fatherNode.right == null){
return fatherNode;
}else{
while(fatherNode.right.equals(pNode)){
pNode = fatherNode;
if(pNode.next == null){
return null;
}
fatherNode = fatherNode.next;
}
return fatherNode;
}
}else{
//有右子樹,求出其子樹中左子樹最左端的節點
pNode = pNode.right;
while(pNode.left != null){
pNode = pNode.left;
}
return pNode;
}
}
}
總結:
- 樹的三種遍歷方式還是不太熟悉;
- 題目的關鍵在於:判斷是否存在右子樹;不存在右子樹的回溯和存在右子樹時找到其右子樹的左子樹的最左端節點。
- 遇到的問題:在while循環的時候,如fatherNode.right.equals(pNode) ,我以爲沒有右子節點的話equals會返回false,其實它會返回空指針異常,這也是遇到好幾次的錯誤!