剑指offer之面试题8:二叉树的下一个结点

题目来自牛客网:https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题目描述:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

/*
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;
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值