面试题7:二叉树的下一个节点
题目描述
给定一棵二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别别指向左右子节点的指针,还有一个指向父节点的指针
例如:这棵树的中序遍历是:D,B,H,E,I,A,F,C,G
解题思路
这套题相比于上一道面试题剑指Offer对答如流系列 - 重建二叉树而言,换汤不换药,还是考察你对二叉树结构的理解。
以这棵树为例:
二叉树的基本结构
//中序以node为根的
public void inOrder(Node node) {
//终止条件
if(node == null) {
return;
}
inOrder(node.left);
System.out.println(node.e);
inOrder(node.right);
}
中序遍历:左子树—> 根结点 —> 右子树(在中间遍历根节点)
//中序以node为根的
public void inOrder(Node node) {
//终止条件
if(node == null) {
return;
}
inOrder(node.left);
System.out.println(node.e);
inOrder(node.right);
}
这棵树的中序遍历为:ACBDFHEMG
既然要求我们找出二叉树的下一个节点,我们就要好好分析中序遍历可能出现的情况,让我们好好捋一下:
以任意一个节点为切入点:
如果我们分析左子树,根据中序遍历的顺序(左子树—> 根结点 —> 右子树)不会得到我们想要的结果。我们只能从右子树进行分析,下面和我一起动笔画画(很重要),找找下一个节点的寻找有哪些场景。
(1)当节点的右子树不为空:节点的下一个节点就是这个节点的右子树中的最左子节点,也就是从右子节点出发一直沿着指向左子节点的指针,走到最后一个叶子节点就是此节点的下一个子节点。
(2)当节点的右子树为空,并且是它父节点的右子树:沿着指向父节点的指针向上遍历,直到找到一个是它父节点的左子节点的节点,那么这个节点的父节点就是我们要找的下一个节点
(3)当结点的右子树为空,且是它父节点的左子节点时,它的下一个节点就是它的父节点
没有别的情况了吧,下面就去实现吧,不要妄想一步到位,第一次写肯定有bug,而且中间穿插着你大量的思考,除非你对二叉树非常非常熟悉了。
书中提供的是C++的树结构,这里我提供Java的
class Node {
int val;
Node left = null;
Node right = null;
Node parent = null;
Node(int val) {
this.val = val;
}
}
解答:
public Node GetNext(Node pNode) {
if (pNode == 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;
}