在二叉树中找到一个节点的后继节点

二叉树中一个节点的后继节点指的是,二叉树的中序遍历的序列中的下一个节点。

链接:https://www.nowcoder.com/questionTerminal/c37ec6a9e4084b9c943be2d3a369e177
来源:牛客网

输入描述: 第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。

以下 n 行每行四个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa
没有左儿子,rch同理)

最后一行输入要询问的节点 node。

输出描述: 输出一个整数表示答案。(如果 node 是最后一个节点,则输出 0 ) 示例1 输入
10 6
6 3 9
3 1 4
1 0 2
2 0 0
4 0 5
5 0 0
9 8 10
10 0 0
8 7 0
7 0 0
10
输出 0

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Map<Integer, TreeNode> map = new HashMap<>();
        Map<Integer, TreeNode> parent = new HashMap<>();
        /**
         * 读取数据
         */
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        TreeNode root = new TreeNode(scanner.nextInt());
        map.put(root.val, root);
        scanner.nextLine();
        for (int i = 0; i < n; i++) {
            int val = scanner.nextInt();
            TreeNode node;
            if (!map.containsKey(val)) {
                node = new TreeNode(val);
                map.put(node.val, node);
            } else {
                node = map.get(val);
            }
            int left = scanner.nextInt();
            if (left != 0) {
                node.left = new TreeNode(left);
                map.put(left, node.left);
                parent.put(left, node);
            } else {
                node.left = null;
            }
            int right = scanner.nextInt();
            if (right != 0) {
                node.right = new TreeNode(right);
                map.put(node.right.val, node.right);
                parent.put(right, node);
            } else {
                node.right = null;
            }
            node.parent = parent.get(node.val);
        }
        Integer target = scanner.nextInt();
        /**
         * 找到 target 的下一个节点
         */
        int result = 0;
        TreeNode node = map.get(target);
        if (node.right != null) {
            // target有右子树:下一个节点就是右子树的最左节点
            node = node.right;
            while (node.left != null) {
                node = node.left;
            }
            result = node.val;
        } else if (node.parent.left == node) {
            // target没有右子树 且 target是其父节点的左子树:后继节点就是target的父节点
            result = node.parent.val;
        } else {
            // target没有右子树 且 target是其父节点的右子树:找到第一个使target在左子树的祖先节点
            node = node.parent;
            while (node.parent != null && node != node.parent.left) {
                node = node.parent;
            }
            result = node.parent.val;
            // target是最后一个节点
            if (node.parent == root) {
                result = 0;
            }
        }
        System.out.println(result);
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode parent;
    public TreeNode(int val) {
        this.val = val;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "val=" + val +
                ", left=" + left +
                ", right=" + right +
                "}\n";
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

beOkWithAnything

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值