8. 二叉树的下一个结点(剑指 Offer 题解Java版)

8. 二叉树的下一个结点

题目链接

牛客网

题目描述

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

public class TreeLinkNode {

    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null; // 指向父结点的指针

    TreeLinkNode(int val) {
        this.val = val;
    }
}

解题思路

我们先来回顾一下中序遍历的过程:先遍历树的左子树,再遍历根节点,最后再遍历右子树。所以最左节点是中序遍历的第一个节点。

void traverse(TreeNode root) {
    if (root == null) return;
    traverse(root.left);
    visit(root);
    traverse(root.right);
}

在这里插入图片描述
① 如果一个节点的右子树不为空,那么该节点的下一个节点是右子树的最左节点;

在这里插入图片描述
② 否则,向上找第一个左链接指向的树包含该节点的祖先节点。
在这里插入图片描述
        1.有右子树的,它的下一个是右子树的最左子节点。(一直沿着指向左子结点的指针找到的叶子节点即为下一个节点)
        2.没有右子树的,且如果它是它父节点的左子节点的话,它的下一个是它的父节点
        3.没有右子树的,且它是它父节店的右子节点的话,它的情况比较复杂,要沿着它父节点上去,直到找到它是它父节点的左子节点为止,那么下一个就是这个父节点。

代码实现

package 二叉树的下一个结点;
/*
作者     :XiangLin
创建时间 :25/02/2020 16:47
文件     :GetNext.java
IDE      :IntelliJ IDEA
*/

public class GetNext {
    public class TreeLinkNode{
        int val;
        TreeLinkNode left = null;
        TreeLinkNode right = null;
        TreeLinkNode next = null;// 指向父结点的指针
        TreeLinkNode(int val){
            this.val = val;
        }
    }
    /*
     * 分析:分几种情况
     * 1.有右子树的,它的下一个是右子树的最左子节点。(一直沿着指向左子结点的指针找到的叶子节点即为下一个节点)
     * 2.没有右子树的,且如果它是它父节点的左子节点的话,它的下一个是它的父节点
     * 3.没有右子树的,且它是它父节店的右子节点的话,它的情况比较复杂,要沿着它父节点上去,直到找到它是它父节点的左子节点为止,那么下一个就是这个父节点。
     */
    public static TreeLinkNode getNext(TreeLinkNode pNode){
        if(pNode == null){
            return null;
        }
        //第1种情况
        if (pNode.right != null){
            TreeLinkNode  node = pNode.right;
            while (node.left != null){
                node = node.left;
            }
           return node;
        }else {
            //第2\3种情况
            while (pNode.next != null){
                TreeLinkNode parent = pNode.next;
                //第2种情况
                if(parent.left == pNode){
                    return parent;
                }
                //如果第2种情况还没达到,就继续向上遍历
                pNode = pNode.next;

            }
            //如果向上遍历到了根节点后,上一个就是尾节点了
            return null;
        }
    }

    public static void main(String[] args) {
        //给定一个二叉树
        GetNext gN = new GetNext();
        TreeLinkNode a = gN.new TreeLinkNode(1);
        TreeLinkNode b = gN.new TreeLinkNode(2);
        TreeLinkNode c = gN.new TreeLinkNode(3);
        TreeLinkNode d = gN.new TreeLinkNode(4);
        TreeLinkNode e = gN.new TreeLinkNode(5);
        TreeLinkNode f = gN.new TreeLinkNode(6);
        TreeLinkNode g = gN.new TreeLinkNode(7);
        TreeLinkNode h = gN.new TreeLinkNode(8);
        TreeLinkNode i = gN.new TreeLinkNode(9);
        a.left = b;
        a.right = c;
        b.left = d;
        b.right = e;
        e.left = h;
        e.right = i;
        c.left = f;
        c.right = g;
        b.next = a;
        c.next = a;
        d.next = b;
        e.next = b;
        h.next = e;
        i.next = e;
        f.next = c;
        g.next = c;
        TreeLinkNode aLinkNode = (TreeLinkNode) getNext(d);
        System.out.println(aLinkNode.val);
    }
}

在这里插入图片描述
个人微信公众号,专注于学习资源、笔记分享,欢迎关注。我们一起成长,一起学习。一直纯真着,善良着,温情地热爱生活。
五角钱的程序员,专注于学习资源、笔记分享。
If you can do what you do best and be happy, you’re further along in life than most people.
只要能把自己做的事做好,并让自己快乐,你就领先于大多数人了。

XiangLin
2020年2月25日于重庆城口
好好学习,天天向上,终有所获

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值