博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构与算法(7) -- 二叉查找树
阅读量:4592 次
发布时间:2019-06-09

本文共 2066 字,大约阅读时间需要 6 分钟。

上一个博客介绍了堆结构,这种结构非常有利于查找最大/最小元素。但是其也有一个非常显著的缺点,对于其他的元素的查找非常困难。这一节将要介绍的是二叉查找树,这种结构保持了这样的特性:其父节点大于左子节点,而小于其右子节点。

另外因为放假的原因将博客停了一段时间,接下来会恢复这个系列。由于后面博主主要打算找java开发相关的岗位,后续的实例代码和讲解可能要偏向于java,这点和之前一直用c++讲解稍有区别。

数据表示

二叉查找树和其他的树结构一样都是基于节点Node的一种数据结构。每个节点都含有一个键、一个值、一条左链接和一条右链接。这里有所不同的是,为了后续某些操作的方便,每个节点还有一个节点计数器。如下代码所示(java):

private class Node {    private Key key;           // 键    private Value val;         // 值    private Node left, right;  // 左和右子节点    private int size;          // 以该节点为根的子树中的节点总数    public Node(Key key, Value val, int size) {        this.key = key;        this.val = val;        this.size = size;    }}

基本操作的分析

查找

在二叉查找树里进行查找是简单的。假设我们在一棵根节点为root的二叉查找树中查找值为value的节点。我们只需将value和root.val相比较就行了,如果value更大,则在右子树里进行查找;反之则在左子树里进行查找。如此迭代下去即可。代码如下:

public Value get(Key key) {    return get(root, key);}private Value get(Node x, Key key) {    if (key == null) throw new IllegalArgumentException("calls get() with a null key");    if (x == null) return null;    int cmp = key.compareTo(x.key);    if      (cmp < 0) return get(x.left, key);    else if (cmp > 0) return get(x.right, key);    else              return x.val;}

插入

插入也是类似的,只不过这里要注意的是:由于插入改变了树的结构,所以一定不要忘了更新被插入元素的size。如果是递归的话,将更新写在最后就能够保证先计算子节点的size,再计算父节点的size,这一点一定要注意,代码如下:

public void put(Key key, Value val) {    if (key == null) throw new IllegalArgumentException("calls put() with a null key");    if (val == null) {        delete(key);        return;    }    root = put(root, key, val);    assert check();}private Node put(Node x, Key key, Value val) {    if (x == null) return new Node(key, val, 1);    int cmp = key.compareTo(x.key);    if      (cmp < 0) x.left  = put(x.left,  key, val);    else if (cmp > 0) x.right = put(x.right, key, val);    else              x.val   = val;    x.size = 1 + size(x.left) + size(x.right);    return x;}

总结

以上就是二叉查找树的两个核心操作了,另外还有更多的代码和操作请戳。由于二叉查找树不能保证树的平衡性,最差的时候其性能会退化到N(平均情况下是1.39lgN)。所以在实际中很少使用,在java集合以及c++ stl中用的是平衡的二叉树,例如红黑树等。这是后一博客要讨论的内容。

参考资料:

《算法》第四版

《STL源码剖析》

See you next time. Happy Coding!!!

转载于:https://www.cnblogs.com/dnhua/p/10437635.html

你可能感兴趣的文章
.35-浅析webpack源码之babel-loader入口文件路径读取
查看>>
VC++ ini文件操作
查看>>
忘记WiFi密码不用怕,一个命令轻松查看你连接过的所有WiFi及密码!
查看>>
魔术方法、魔术常量
查看>>
Eclipse搭建Struts2环境
查看>>
设备管理,连接两个数据库,用的easygui
查看>>
Ucore lab1实验报告
查看>>
算法导论之插入排序和归并排序
查看>>
VC++中对话框界面重绘1-概述
查看>>
正则例子
查看>>
简介---linux内核态和用户态
查看>>
MIT Python 第四课函数抽象与递归简介 函数调用与原代码的区别
查看>>
C++Primer第五版——习题答案详解(三)
查看>>
解决Google Play审核中的WebViewClient.onReceivedSslError问题
查看>>
如何清除浮动
查看>>
SpringBoot系列: Maven多项目管理
查看>>
ReactNative--state
查看>>
从别人的博客学习
查看>>
spring4的新特性---泛型注入
查看>>
在linux上安装MySQL数据库,并简单设置用户密码,登录MySQL
查看>>