二叉搜索树中的中序后继

二叉搜索树中的中序后继

前言

二叉搜索树的特性需要好好利用,与中序遍历紧密相关。有时还可以通过左<中<右来非递归寻找节点值。

一、案例

在这里插入图片描述

二、题解

package com.xhu.offer.offerII;

//二叉搜索树中的中序后继
public class InorderSuccessor {
    //中序遍历
    //总结:二叉搜索树的特性需要好好利用,与中序遍历紧密相关。有时还可以通过左<中<右来非递归寻找节点值。
    TreeNode dummyNode = new TreeNode(-1);
    boolean flag = false, flag2 = false;

    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        inOrder(root, p);

        return dummyNode.right;
    }

    private void inOrder(TreeNode root, TreeNode p) {
        //剪枝
        if (flag2 || root == null) return;

        inOrder(root.left, p);
        if (flag) {
            flag = false;
            flag2 = true;
            dummyNode.right = root;
        }
        if (p.val == root.val) flag = true;
        inOrder(root.right, p);
    }

    //优化
    TreeNode res = null;

    public TreeNode inorderSuccessor2(TreeNode root, TreeNode p) {
        if (root == null) return res;

        inorderSuccessor2(root, p);
        if (root.val > p.val && !flag) {
            flag = true;
            res = root;
            return res;
        }
        inorderSuccessor2(root, p);

        return res;
    }

    //优化,简单递归
    //总结:这种复制地址的方式可以做到类似成员变量的效果,但是需分成两个函数写,好处是比堆中取要快一些,这些局部变量存在于线程私有栈中。
    public TreeNode inorderSuccessor3(TreeNode root, TreeNode p) {
        boolean[] flag = new boolean[]{false};
        TreeNode[] res = new TreeNode[]{null};
        order(root, p, flag, res);
        return res[0];
    }

    private void order(TreeNode root, TreeNode p, boolean[] flag, TreeNode res[]) {
        if (flag[0] || root == null) return;

        order(root.left, p, flag, res);
        if (p.val < root.val && !flag[0]) {
            flag[0] = true;
            res[0] = root;
        }
        order(root.right, p, flag, res);
    }

    // Definition for a binary tree node.
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

}

总结

1)二叉搜索树的特性需要好好利用,与中序遍历紧密相关。有时还可以通过左<中<右来非递归寻找节点值。
2)复制地址的方式可以做到类似成员变量的效果,但是需分成两个函数写,好处是比堆中取要快一些,这些局部变量存在于线程私有栈中。

参考文献

[1] LeetCode 原题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值