Java 查找二叉树中某一结点的前驱结点以及后继结点

前言

给定二叉树结点定义Node结构如下,其中parent结点指向当前Node结点的父结点,根结点指向null

    private static class Node {
        public int value;
        public Node left;
        public Node right;
        /**
         * 指向父结点,头结点指向null
         */
        public Node parent;

        public Node(int value) {
            this.value = value;
        }
    }

什么是后继结点

定义:在二叉树的中序遍历的序列中,Node的下一个节点叫作Node的后继节点。

什么是前驱结点

定义:在二叉树的中序遍历的序列中,Node的前一个节点叫作Node的前驱节点。

代码实现

查找某一结点的后继结点

思路

根据中序遍历的顺序可以得出如下结论:

  1. 如果该结点存在右子树,则该结点对应的后继结点为其右子树上最左的结点;
  2. 如果该结点不存在右子树,向上查找,如果某个结点的parent结点的左子树等于该node结点,则此parent结点为后继结点
代码实现
 /**
     * 获取某个结点的后继结点
     *
     * @param node
     * @return
     */
    private static Node getSuccessorNode(Node node) {
        if (node == null) {
            return node;
        }
        if (node.right != null) {
            //1.当node结点存在右子树,则后继结点为Node结点右子树最左边结点
            return getLeftMost(node.right);
        } else {
            //当前Node结点没有右子树,则向上查找;
            //某个结点的parent结点的左子树 == node结点,则此parent结点即为后继结点
            Node parent = node.parent;
            while (parent != null && parent.left != node) {
                node = parent;
                parent = node.parent;
            }
            return parent;

        }
    }
    
   /**
     * 获取某个结点最左结点
     *
     * @param node
     * @return
     */
    private static Node getLeftMost(Node node) {
        if (node == null) {
            return node;
        }
        while (node.left != null) {
            node = node.left;
        }
        return node;
    }

图解

后继结点查找

查找某一结点的前驱结点

思路

与查找后继结点相类似,根据中序遍历顺序同样可以得出如下结论:

  1. 如果该结点存在左子树,则该结点对应的前驱结点为其左子树上最右的结点;
  2. 如果该结点不存在左子树,向上查找,如果某个结点的parent结点的右子树等于该node结点,则此parent结点为前驱结点
代码实现
    /**
     * 获取某一Node结点对应的前驱结点
     *
     * @param node
     * @return
     */
    private static Node getPrecursorNode(Node node) {
        if (node == null) {
            return node;
        }
        if (node.left != null) {
            //1.当node结点存在左子树,则前驱结点为Node结点左子树最右边结点
            return getRightMost(node.left);
        } else {
            //当前Node结点没有左子树,则向上查找;
            //某个结点的parent结点的右子树 == node结点,则此parent结点即为后继结点
            Node parent = node.parent;
            while (parent != null && parent.right != node) {
                    node = parent;
                    parent = node.parent;
            }
            return parent;
        }
    }

  /**
     * 获取某一结点最右结点
     *
     * @param node
     */
    private static Node getRightMost(Node node) {
        if (node == null) {
            return node;
        }
        while (node.right != null) {
            node = node.right;
        }
        return node;
    }
图解

查找某一结点的前驱结点

测试用例

  public static void main(String[] args) {
        Node node = new Node(1);
        node.parent = null;

        node.left = new Node(2);
        node.left.parent = node;

        node.right = new Node(3);
        node.right.parent = node;

        node.left.left = new Node(4);
        node.left.left.parent = node.left;

        node.left.right = new Node(5);
        node.left.right.parent = node.left;

        node.left.right.left = new Node(6);
        node.left.right.left.parent = node.left.right;

        node.left.right.right = new Node(7);
        node.left.right.right.parent = node.left.right;
        Node target = node.left.right.left;
        System.out.println(target.value + "的后继结点为:" + getSuccessorNode(target).value);
        System.out.println(target.value + "的前驱结点为:" +getPrecursorNode(target).value);
    }

运行结果

6的后继结点为:5
6的前驱结点为:2

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值