详解二叉搜索树(binary search tree)

package com.datastructure;

/**
 * 二叉搜索树(binary search tree)
 * <p>
 * 1.满足条件:
 * 对于根节点,左子树中所有节点的值< 根节点的值<右子树中所有节点的值;
 * 任意节点的左、右子树也是二叉树搜索树,即满足上面条件
 * <p>
 * 2.二叉搜索树的中序遍历序列是升序的
 * <p>
 * 3.二叉搜索树常见应用:
 * 用作系统中的多级索引,实现高效的查找、插入、删除操作;
 * 作为一些搜索算法的底层数据结构
 * 用于存储数据流,以保存起有序状态
 */
public class BinarySearchTree {


    private TreeNode root;

    /**
     * 构造方法
     */
    public BinarySearchTree() {
        // 初始化空树
        root = null;
    }

    /**
     * 获取二叉树根节点
     */
    public TreeNode getRoot() {
        return root;
    }

    /**
     * 查找节点
     */
    public TreeNode search(int num) {
        TreeNode cur = root;
        //循环查找,越过叶子节点后跳出
        while (cur != null) {

            if (cur.val < num) { //目标节点在cur的右子树中
                cur = cur.right;
            } else if (cur.val > num) { //目标节点在cur的左子树中
                cur = cur.left;
            } else {// 找到目标节点,跳出循环
                break;
            }

        }
        //返回目标节点
        return cur;
    }

    /**
     * 插入节点
     * 时间复杂度O(logn)
     */
    public void insert(int num) {
        //若树为空,则初始化根节点
        if (root == null) {
            root = new TreeNode(num);
            return;
        }
        TreeNode cur = root;
        TreeNode pre = null;
        //循环查找,越过叶节点后跳出
        while (cur != null) {
            //找到重复节点,直接返回
            if (cur.val == num)
                return;
            pre = cur;


            if (cur.val < num)  //插入位置在cur的右子树中
                cur = cur.right;
            else//插入位置在 cur 的左子树中
                cur = cur.left;
        }
        //插入节点
        TreeNode node = new TreeNode(num);
        if (pre.val < num)
            pre.right = node;
        else
            pre.left = node;
    }

    /**
     * 删除节点:先在二叉树中查找到目标节点,然后将其删除
     */
    public void remove(int num) {
        //若树为空,直接提前返回
        if (root == null)
            return;
        TreeNode cur = root;
        TreeNode pre = null;
        //循环查找,越过子节点后跳出
        while (cur != null) {
            //找到待删除节点,跳出循环
            if (cur.val == num)
                break;
            pre = cur;
            if (cur.val < num)//待删除节点在cur的右子树中
                cur = cur.right;
            else//待删除节点在cur的左子树中
                cur = cur.left;

        }
        //若无待删除节点,则直接返回
        if (cur == null)
            return;
        //子节点数量=0 or 1
        if (cur.left == null || cur.right == null) {
            //当子节点数量=0 或1时,child=null
            TreeNode child = cur.left != null ? cur.left : cur.right;
            //删除节点cur
            if (cur != root) {
                if (pre.left == cur)
                    pre.left = child;
                else
                    pre.right = child;
            } else {
                //若删除节点为根节点,则重新指定根节点
                root = child;
            }
        } else {//子节点数量=2
            //获取中序遍历中cur的下一个节点
            TreeNode tmp = cur.right;
            while (tmp.left != null) {
                tmp = tmp.left;
            }
            //递归删除节点tmp
            remove(tmp.val);
            //用tmp覆盖cur
            cur.val = tmp.val;
        }
    }

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值