二叉查找树(Binary Sort Tree)的解析与实现

本文介绍了二叉查找树(Binary Sort Tree)的概念、性质及其实现,包括查找、查找最大值与最小值、插入、删除等操作。讨论了二叉查找树的自平衡问题,并提供了完整的Java代码实现。
摘要由CSDN通过智能技术生成

个人博客:二叉查找树(Binary Sort Tree)的解析与实现

二叉查找树

        关于性质之类的可以参考wiki、百度百科或者其他博客,其实也很简单,推荐看标准的描述。而博主写的内容主要是想写成类似Map底层的。所以有泛型,并且是Key-Value结构。关于二叉查找树,我们一般是类比二分搜索,仿佛跟Key-Value这样的结构并不一致。但是,在Java上,如果我们能在定义节点的时候,专门声明了Key与Value,并且在Key上定义comparator,那么就是通过对Key的排序,获取一个顺序序列,并且根据Key可以找到对应的Value。这也是Java容器TreeMap与TreeSet的底层是红黑树的原因(其实差不多啦,红黑树可以自平衡)

        那么如果说红黑树是二叉查找树的升级版,因为红黑树是保证平衡的,也就可以理解为什么Map的底层是一棵红黑树。我们这样来定义树,也可以完成Key-Value的模式。从而支持高效查找。例如下图:

对于这些结点,编号就是Key,名字就是Value,如果设定Key的comparator,那么就按照编号来排序,在搜索某个编号的时候就能以O(logn)的复杂度搜索到对应的人的名字。

二叉查找树的定义与结点的定义

        key与value是必须的,此外,想要同时对key定义一个comparator。由于Java语言,我们可以声明一个BST类,其中的内部类(或者可以专门写出来)可以有Node作为结点。那么可以这样来写:

class BST<Key extends Comparable<Key>, Value>{
    private Node root;

    private class Node{
        private Key key;
        private Value value;
        private Node left;
        private Node right;
        private Node father;
        
        public Node(Key key,Value value){
            this.key = key;
            this.value = value;
        }
    }
}

泛型是必要的,并且让Key继承Comparable,这样,我们在实际算法中,使用compareTo方法,就可以进行比较。使用的话,先new出来BST对象,然后调用例如put、get方法等等,这个后面再实现。

        关于father结点,如果是递归的算法,father就可以不用了,在回溯的时候就可以处理。但是非递归的算法,虽然也可以用last等来代替,但是并不好,推荐使用father结点,非常方便。当然也是一个额外开销(但是真的微不足道)。

二叉查找树的查找

        很简单,就跟二分一样,从根开始搜,如果比该结点的key小,那么则进入左子树,大则进入右子树。若相等,则表示搜索到了,若最终搜索到null仍未找到,那么就返回未搜索到。

        自然,递归是非常简单明了的表现方式,但是递归的效率相对略低,但是比较容易理解。这里先写一个递归的写法:

public Value get(Key key){
    if(key == null) return null;
    return get(this.root,key);
}
public Value get(Node root,Key key){
    if(root == null) return null;
    int cmp = key.compareTo(root.key);
    if(cmp == 0){
        return root.value;
    }else{
        if(cmp < 0){
            return get(root.left,key);
        }else{
            return get(root.right,key);
        }
    }
}

还是比较简单明了的,其实转化成非递归也非常容易:

public Value get(Key key){
    if(key == null) return null;
    return get(this.root,key);
}
public Value get(Node root,Key key){
    while(root != null){
        int cm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值