二叉查找树(2)-二叉树-数据结构和算法(Java)

1 范围查找keys()

既然是范围查找呢,需要遍历整个二叉树,上一篇我们讲解了二叉树遍历,这里我们就需要用到。

以中序遍历为例,范围 [ l o , h i ] [lo,hi] [lo,hi]算法如下:

  • 遍历二者查找树,如果当前节点 l o ≤ k e y ≤ h i lo\le key\le hi lokeyhi,符合要求

代码如下:

/**
 * [lo,hi]范围内键的迭代器
 * @param lo    范围下限
 * @param hi    范围上限
 * @return      范围内键的迭代器
 */
@Override
public Iterable<K> keys(K lo, K hi) {
    Queue<K> q = new LinkQueue<>();

    Stack<Node<K, V>> l = new Stack<>();
    Node<K, V> current = root;

    while (current != null || !l.isEmpty()) {
        while (current != null) {
            l.push(current);
            current = current.left;
        }
        if (!l.isEmpty()) {
            current = l.pop();
            if (lo.compareTo(current.key) <= 0 && hi.compareTo(current.key) >= 0) {
                q.offer(current.key);
            }
            current = current.right;
        }
    }

    return q;
}

2 性能分析

二叉查找树中和有序性有关的操作的性能如何?要研究这个问题,我们首先要知道树的高度(任意节点的最大深度或称树的深度)。给定一棵树,树的高度决定了所有操作在最坏的情况下的性能(我们实现的范围查找增长数量级N)

在一棵二叉查找树中,所有操作在最坏情况下所需的时间都和树的高度成正比。

目前位置3中符号表实现成本比较,如下表:

下面看下符号表的初始实现的性能特点,如下表4-1所示:

算法(数据结构)最坏情况下的成本
(N次插入后)
平均情况下的成本
(N次随机插入后)
算法高效的支持有序
性相关的操作
查找插入查找插入
顺序查找(无序链表)NNN/2N
二分查找(有序数组)lgNN+lgNlgNN+lgN
二叉查找树NN1.39lgN1.39lgN

3 综合测试

代码如下:

public class TestBst {
    public static void main(String[] args) {
        testBst();

    }

    public static void testBst() {
        BST<Integer, String> bst = new BST<>();
        bst.put(33, "a");
        bst.put(23, "b");
        bst.put(82, "c");
        bst.put(3, "d");
        bst.put(25, "e");
        bst.put(70, "f");
        bst.put(100, "g");
        System.out.println("初 始:" + bst);

        Integer key = 3;
//        System.out.println(key + "-" + bst.get(key));
//
//        System.out.println("最大键: " + bst.max());
//        System.out.println("最小键: " + bst.min());
//
//        key = 5;
//        System.out.println(key + " 向上取整:" + bst.ceiling(key));
//        System.out.println( key + " 向下取整:" + bst.floor(key));
//        key = 26;
//        int index = bst.rank(key);
//        System.out.println("rank(" + key + ")=" + index);
//        System.out.println("select(" + index + ")=" + bst.select(index));

//        key = 70;
//        System.out.println("删除: " + key + "=" + bst.delete(key));
//        System.out.println("删除后: " + bst);

//        System.out.println("删除最小键: " + bst.deleteMin());
//        System.out.println("删除后:" + bst);
//        System.out.println("删除最大键: " + bst.deleteMax());
//        System.out.println("删除后:" + bst);

        int lo = 0, hi = 80;
        Iterator<Integer> iterator = bst.keys(lo, hi).iterator();
        System.out.println("范围查找:" + lo + "~" + hi);
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
        System.out.println();
    }
}

我目前没测出bug,如果小伙伴有测出bug或者其他可以联系我或者留言。

4 后记

​ 如果小伙伴什么问题或者指教,欢迎交流。

❓QQ:806797785

⭐️源代码仓库地址:https://gitee.com/gaogzhen/algorithm

参考:

[1][美]Robert Sedgewich,[美]Kevin Wayne著;谢路云译.算法:第4版[M].北京:人民邮电出版社,2012.10

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

gaog2zh

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

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

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

打赏作者

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

抵扣说明:

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

余额充值