剑指offer面试题8(java版):二叉树的下一个节点

welcome to my blog

剑指offer面试题8(java版):二叉树的下一个节点

题目描述

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

思路

  • 要弄清楚中序遍历
  • 具体思路见注释

复杂度

  • 时间复杂度: 和数的深度有关
  • 空间复杂度: 没有分配额外的空间, O(1)
第三次做, 按照当前节点有无右子树分类两类进行讨论; 中序遍历是左根右, 如有当前节点没有右子树, 那么他的下一个节点有两种可能, 一种是null, 另一种是某个节点; 结果是某个节点时说明当前节点在某个节点的左子树中; 赋值名称要有意义, curr指向pNode, father指向curr.next
public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        if(pNode==null)
            return null;
        TreeLinkNode curr;
        //有右子树
        if(pNode.right!=null){
            curr = pNode.right;
            while(curr.left!=null)
                curr = curr.left;
            return curr;
        }
        //没有右子树; 需要向上找到这样一个节点, 使得pNode在该节点的左子树中
        else{
            //curr指向当前节点pNode
            curr = pNode; 
            ///father是curr的父节点
            TreeLinkNode father = pNode.next;
            //如果pNode是根节点, 就没有下一个节点了
            if(father==null)
                return null;
            //
            while(father!=null && father.right==curr){
                curr = father;
                father = father.next;
            }
            //here, father==null || father.left==curr
            return father;
        }
    }
}
第二次做, 根据当前节点有无右子树分为两大类情况进行讨论; 最麻烦的情况是当前节点没有右子树, 如果当前节点是父节点的左孩子则返回当前节点, 否则继续向上遍历,细节见代码
public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        if(pNode==null)
            return null;
        if(pNode.right != null){
            TreeLinkNode curr = pNode.right;
            while(curr.left!=null)
                curr = curr.left;
            return curr;
        }
        else{//没有右子树
            //当前节点是根节点
            if(pNode.next==null)
                return null;
            TreeLinkNode curr = pNode, p = curr.next;
            //当前节点的父节点是根节点
            if(p.next==null){
                if(p.left==curr)
                    return p;
                return null;
            }
            while(p!=null){
                if(p.left==curr)
                    return p;
                curr = p;
                p = p.next;
            }
            return null;
        }
    }
}
/*
public class TreeLinkNode {
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;

    TreeLinkNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        // 健壮性判断
        if(pNode == null)
            return null;
        // 开始正常执行
        /*
        首先明确当前节点的下一个节点由其右子树或者祖先节点决定, 跟它的左子树没有关系
        1.当前节点有右子树,则下一个节点是右子树中最左子节点
        2.当前节点没有右子树
            2.1当前节点有父节点
                2.1.1当前节点是其父节点的左子节点, 则下一个节点是当前节点的父节点
                2.1.2当前节点是其父节点的右子节点, 当前节点的父节点记作p
                    2.1.2.1向上遍历p的父节点,直到找到这样一个节点, 该节点是其父节点的左子节点
                    2.1.2.2向上遍历p的父节点,如果遇到null,则说明当前节点是最后一个节点,没有下一个节点
            2.2当前节点没有父节点
                说明当前节点是最后一个节点, 没有下一个节点了, 返回null
        可以看出,上面总共有2大类情况
        */
        //1.
        if(pNode.right != null){
            TreeLinkNode curr = pNode.right;
            while(curr.left != null){
                curr = curr.left;
            }
            return curr;
        }
        //2.1
        if(pNode.next != null){
            TreeLinkNode curr = pNode.next;
            //2.1.1
            if(pNode == curr.left)
                return curr;
            //2.1.2 (包括了2.1.2.1和2.1.2.2)
            TreeLinkNode father = curr.next;
            while(father != null && curr == father.right ){
                curr = father;
                father = curr.next; //如果father是null了, 则while判断中的father.right就会报错,所以需要扩充while中的条件
            }
            return father;
        }
        //2.2
        return null;
        
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值