题目描述:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
/*
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
*/
值得一提的是不知道为什么牛客网上的父亲节点要写成next。
思路:这里要提一下中序遍历是什么,就是左中右,这个顺序。如下图的二叉树中序遍历的序列为:{d,b,h,e,i,a,f,c,g}。可以找到如下规律,将结点分为三类。
(1)该结点具有右子树(结点),此时只要找到右子树中的最左子结点即可。例如b,b有右子树,则找右子树的最左子结点,为h。
(2)该结点不具有右子树(结点),且该结点为父结点的左子结点,此时下一个结点就为父结点,比如d,d为b的左子结点,于是下一个就为d的父结点b。
(3)该结点不具有右子树(结点),且该结点为父结点的右子结点,此时就不好判断了,我们需要去找该结点的父节点,去判断这个父节点是否为父结点的左结点,如果为左子节点,则返回父结点的父结点。例如i,为e的右子节点,且不具有右子树,则取判断e,e不是b的左子节点,则继续判断结点b,结点b是a的左子节点,则下一个结点为a。
贴出代码:需要注意的一点就是防止抛出java.lang.NullPointerException这个异常,要先去判断结点是否为空,要把判断放在前面,不能用null的结点进行操作。最后还要在不符合这些情况下,返回一个null。不符合上述三种情况的情况为:5,4,#,3,#,2。即,从上往下都是左结点,然后判断5的下一个结点。5没有右结点,且没有父结点,所以为最特殊的情况,此时要返回null。
/*
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
*/
//三种情况,1.首先,该结点包含右子树,这该结点的下一个结点为右子树中的最左子节点
//2.如果该结点不包含右子树,且该结点为父结点的左子结点,则该节点的下一个为父结点。
//3.如果该结点不包含右子树,且该结点且为父结点的右子结点,就往上寻找父结点,直到找到该结点是
// 其父节点的左子节点的值,这个节点的父结点就是我们要找的结点,
//核心就是要小心出现异常的情况
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode)
{
if(pNode==null)
return null;
//包含右子树
if(pNode.right!=null)
{
TreeLinkNode node = pNode.right;
while(node.left!=null)
{
node=node.left;
}
return node;
}
else if(pNode.next!=null&&pNode.next.left!=null&&pNode.next.left==pNode)
{
return pNode.next;
}
else if(pNode.next!=null&&pNode.next.right ==pNode)
{
TreeLinkNode node = pNode.next;
while(node.next!=null&&node!=node.next.left)
{
node=node.next;
}
return node.next;
}
return null;
}
}