本文參考自《劍指offer》一書,代碼采用Java語言。
題目
給定一棵二叉樹和其中的一個結點,如何找出中序遍歷順序的下一個結點? 樹中的結點除了有兩個分別指向左右子結點的指針以外,還有一個指向父結點的指針。
思路
首先自己在草稿紙上畫圖,進行分析(不再展開)。可以發現下一個結點的規律為:
1.若當前結點有右子樹時,其下一個結點為右子樹中最左子結點;
2.若當前結點無右子樹時,
(1)若當前結點為其父結點的左子結點時,其下一個結點為其父結點;
(2)若當前結點為其父結點的右子結點時,繼續向上遍歷父結點的父結點,直到找到一個結點是其父結點的左子結點(與(1)中判斷相同),該結點即為下一結點。
測試用例
1.正常二叉樹
2.左斜樹、右斜樹
4.單個結點
5.null
6.不同位置結點的下一結點(即上面分析的幾種情況、無下一節點等情況)
完整Java代碼
(含測試代碼)
由於樹的生成較為繁瑣,下面不含全部測試代碼,但主體代碼已經通過了牛客網中的測試,可以保證沒有問題。
/**
*
* @Description 二叉樹的下一個結點
*
* @author yongh
* @date 2018年9月12日 下午7:20:45
*/
// 題目:給定一棵二叉樹和其中的一個結點,如何找出中序遍歷順序的下一個結點?
// 樹中的結點除了有兩個分別指向左右子結點的指針以外,還有一個指向父結點的指針。
public class NextNodeInBinaryTrees {
private class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode parent = null;
TreeLinkNode(int val) {
this.val = val;
}
}
public TreeLinkNode GetNext(TreeLinkNode pNode) {
if (pNode == null) {
System.out.print("結點為null ");
return null;
}
if (pNode.right != null) {
pNode = pNode.right;
while(pNode.left!=null)
pNode=pNode.left;
return pNode;
}
while(pNode.parent !=null){
if(pNode==pNode.parent .left)
return pNode.parent;
pNode=pNode.parent;
}
return null;
}
// ==================================測試代碼==================================
//創建樹較為繁瑣,未包括所有測試代碼。
public void test1() {
TreeLinkNode node = null;
TreeLinkNode nextNode = GetNext(node);
if(nextNode!=null)
System.out.println(nextNode.val);
else
System.out.println("無下一結點");
}
public void test2() {
TreeLinkNode node1 = new TreeLinkNode(1);
TreeLinkNode node2 = new TreeLinkNode(2);
TreeLinkNode node3 = new TreeLinkNode(3);
TreeLinkNode node4 = new TreeLinkNode(4);
node1.left = node2;
node1.right = node3;
node2.parent = node1;
node3.parent = node1;
node4.left=node1;
node1.parent=node4;
TreeLinkNode nextNodeOf1=GetNext(node1);
TreeLinkNode nextNodeOf2=GetNext(node2);
TreeLinkNode nextNodeOf3=GetNext(node3);
TreeLinkNode nextNodeOf4=GetNext(node4);
if(nextNodeOf1!=null)
System.out.println("1結點的下一個結點值為:"+nextNodeOf1.val);
else
System.out.println("1結點無下一結點");
if(nextNodeOf2!=null)
System.out.println("2結點的下一個結點值為:"+nextNodeOf2.val);
else
System.out.println("2結點無下一結點");
if(nextNodeOf3!=null)
System.out.println("3結點的下一個結點值為:"+nextNodeOf3.val);
else
System.out.println("3結點無下一結點");
if(nextNodeOf4!=null)
System.out.println("4結點的下一個結點值為:"+nextNodeOf4.val);
else
System.out.println("4結點無下一結點");
}
public static void main(String[] args) {
NextNodeInBinaryTrees demo = new NextNodeInBinaryTrees();
System.out.print("test1:");
demo.test1();
System.out.print("test2:");
demo.test2();
}
}
test1:結點為null 無下一結點 test2:1結點的下一個結點值為:3 2結點的下一個結點值為:1 3結點的下一個結點值為:4 4結點無下一結點
收獲
1.在面對復雜問題時要學會畫圖和舉例分析
2.在分情況討論時,一定要考慮到所有情況,這些都是在寫代碼前需要考慮到的。
