今天做题时遇到的一个很有意思的解法,所以记录下来吧!
二叉树的下一个节点
描述
给定一棵二叉树的其中一个节点,请找出中序遍历序列的下一个节点。
样例
假定二叉树是:[2, 1, 3, null, null, null, null], 给出的是值等于2的节点。
则返回的应当是:3
解析:
中序遍历结果:1,2,3
则 2 的下一个节点为:3
思路
这个题实际上想说的是找一个节点的后继节点:
- 当一个节点node,它有右孩子,那就沿着其右孩子找,找到右孩子的最左端,最左端的节点即为node在中序遍历序列中的下一个节点。
- 当一个节点node,它没有右孩子时,我们就沿着其父亲节点向上找,直到该父节点是该父节点的父节点的左孩子(爸爸是祖父的左孩子),这个祖父就是node在中序遍历序列中的下一个节点。
如果找不到这样的节点,就表示没有后继。
还是不太明白?先来看这个栗子:
中序遍历序列为:
D B H E A F C N G
假如:我要找A在中序遍历序列中的下一个节点
很明显,在上述遍历序列中,我们可以看到,A的下一个节点为 F
那么在树中查找的情况则为:
A需要先找到它的右孩子C,再往下走,走到头了,找到了C的左孩子F。
这又能说明什么呢?先别急,我们找找规律
假如:给定节点E,找E下一个节点
中序遍历序列中可以看到 E的下一个节点为:A
看图:
我们需要先找到E的父亲B,再向上找,找到A节点。
代码
public class Main {
public static TreeNode inorderSuccessor(TreeNode p) {
if (p==null){
return null;
}
//先判断p节点是否有右孩子
if (p.right!=null){
//有右孩子,就找到右孩子,再往最左端找
p=p.right;
while (p.left!=null){
p=p.left;
}
//最左端的节点就是P的下一个节点(后继)
return p;
}
//如果P没有右孩子,就向上找,如果p节点的父节点是p节点的祖父节点的左孩子(可以说P是祖父节点的右孙子)
while (p.father!=null && p==p.father.right){
p=p.father;
}
//返回P的父亲的父亲
return p.father;
}
}
上述如有理解有误或表述不当的地方,还请批评指正,谢谢!