算法—二叉查找树的相关一些操作及总结
二叉查找树得以广泛应用的一个重要原因就是它能够保持键的有序性,因此它可以作为实现有序符号表API中的众多方法的基础。这使得符号表的用例不仅能够通过键还能通过键的相对顺序来访问键值对。下面,我们要研究有序符号表API中各个方法的实现。
1.最大键和最小键
如果根结点的左链接为空,那么一棵二叉查找树中最小的键就是根结点;如果左链接非空,那么树中的最小键就是左子树中的最小键。简单的循环也能等价实现这段描述,但为了保持一致性我们使用了递归。找出最大键的方法也是类似的,只是变为查找右子树而已。
2.向上取整和向下取整
如果给定的键key小于二叉查找树的根结点的键,那么小于等于key的最大键(floor)一定在根结点的左子树中;如果给定的键key大于二叉查找树的根结点,那么只有当根结点右子树中存在小于等于key的结点时,小于等于key的最大键才会出现在右子树中,否则根结点就是小于等于key的最大键。这段描述说明了floor()方法的递归实现,同时也递推地证明了它能够计算出预期的结果。将“左”变为“右”(同时将小于变为大于)就能够得到ceiling()的算法。向上取整函数的计算如下图所示。
3.选择操作
二叉查找树中的选择操作和之前我们学习过的基于切分的数组选择操作类似。我们在二叉查找树的每个结点中维护的子树结点计数器变量N就是用来支持此操作的。
4.select()方法
5.删除最大键和删除最小键
二叉查找树中最难实现的方法就是delete()方法,即从符号表中删除一个键值对。作为热身运动,我们先考虑deleteMin()方法(删除最小键所对应的键值对),如下图所示,和put()一样,我们的递归方法接受一个指向结点的链接,并返回一个指向结点的链接。这样我们就能够方便地改变树的结构,将返回的链接赋给作为参数的链接。对于deleteMin(),我们要不断深入根结点的左子树中直至遇见一个空链接,然后将指向该结点的链接指向该结点的右子树(只需要在递归调用中返回它的右链接即可)。此时已经没有任何链接指向要被删除的结点,因此它会被垃圾收集器清理掉。我们给出的标准递归代码在删除结点后会正确地设置它的父结点的链接并更新它到根结点的路径上的所有结点的计数器的值。deleteMax()方法的实现和deleteMin()完全类似。
6.删除操作
我们可以用类似的方式删除任意只有一个子结点(或者没有子结点)的结点,但应该怎样删除一个拥有两个子结点的结点呢?删除之后我们要处理两棵子树,但被删除结点的父结点只有一条空出来的链接。第一个方法,在删除结点x后用它的后继结点填补它的位置。因为x有一个右子结点,因此它的后继结点就是其右子树中的最小结点。这样的替换仍然能够保证树的有序性,因为x.key和它的后继结点的键之间不存在其他的键。我们能够用4个简单的步骤完成将x替换为它的后继结点的任务(具体过程如下图所示):
Ο将指向即将被删除的结点的链接保存为t;
Ο将x指向它的后继结点min(t.right);
Ο将x的右链接(原本指向一棵所有结点都大于x.key的二叉查找树)指向deleteMin(t.right),也就是在删除后所有结点仍然都大于x.key的子二叉查找树。
Ο将x的左链接(本为空)设为t.left(其下所有的键都小于被删除的结点和它的后继结点)。
7.范围查找
为了确保以给定结点为根的子树中所有在指定范围之内的键加入队列,我们会(递归地)查找根结点的左子树,然后查找根结点,然后(递归地)查找根结点的右子树。
8.性能分析
二叉查找树中和有序性相关的操作的效率如何?要研究这个问题,我们首先要知道树的高度(即树中任意结点的最大深度)。给定一棵树,树的高度决定了所有操作在最坏情况下的性能(范围查找除外,因为它的额外成本和返回的键的数量成正比)。
命题:在一棵二叉查找树中,所有操作在最坏情况下所需的时间都和树的高度成正比。
证明:树的所有操作都沿着树的一条或两条路径行进。根据定义,路径的长度不可能大于树的高度。
9.总结
在某些场景中二叉查找树在最坏情况下的恶劣性能仍然是不可接受的。二叉查找树的基本实现的良好性能依赖于其中的键的分布足够随机以消除长路径。对于快速排序,我们可以先将数组打乱;而对于符号表的API,我们无能为力,因为符号表的用例控制着各种操作的先后顺序。
转载于:https://www.cnblogs.com/joey-hua/p/5010848.html
算法—二叉查找树的相关一些操作及总结相关推荐
- Java实现二叉查找树及其相关操作
目录 二叉查找树 初始化 二叉查找树的查找 二叉查找树的插入 二叉查找树的删除 二叉查找树的中序遍历 findMax and findMin 二叉查找树完整代码 测试用例 完整代码已上传至gitee中 ...
- 数据结构与算法--二叉查找树转顺序排列双向链表
二叉查找树转顺序排列双向链表 题目:输入一颗二叉查找树,将二叉查找树转成一个排序的双向链表,要求不能创建任何新节点,只调整树节点中指针的指向.例如下图所示: 本次二叉查找树节点定义使用之前文章 数据结 ...
- JAVA的静态方法的运算_java. util.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作。...
java. util.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作. /* public static double abs ( double num):获取绝对值 ...
- java 面向对账 抽象_java开发银行支付、对账时证书相关的操作实例
java 开发银行支付.对账时证书相关的操作总结. 证书的相关操作主要是在CMD窗口使用keytool工具Keytool 是一个Java数据证书的管理工具 ,Keytool将密钥(key)和证书(ce ...
- 怎样将树的中序遍历的数输入到一个数组中_数据结构与算法-二叉查找树平衡(DSW)...
上一节探讨了二叉查找树的基本操作,二叉查找树的查找效率在理想状态下是O(lgn),使用该树进行查找总是比链表快得多.但是,该论点并不总是正确,因为查找效率和二叉树的形状息息相关.就像这样: 图1-1给 ...
- 叶子结点和分支节点_教你玩转二叉查找树的结点插入操作
上一篇文章已经介绍过了二叉查找树的基本概念与查找结点的操作,本文继续介绍二叉查找树插入结点的操作. 二叉查找树的插入 现有只有一个结点的二叉查找树,该结点的值为50,现在我要往这颗二叉查找树依次插入9 ...
- 算法与程序设计相关知识
编写计算机程序解决问题的基本过程 五步: 分析问题.设计算法.编写程序.调试运行.检测结果. 算法的概念,掌握算法的描述方法,能从简单问题出发,设计出解决实际问题的算法: 算法概念:一种解决问题的方法 ...
- Linux中和文件相关的操作
Linux中和文件(/文件夹)相关的操作 1. 文件:删除.复制.移动.创建链接 2. 文件的解压 和 压缩 3. 文件:列举查看.大小查看.个数统计 3.1 `ls`:文件列举查看 3.2 `ls. ...
- CV之MTCNN:MTCNN算法过程及其相关思路配图集合
MTCNN算法过程及其相关思路配图集合 目录 MTCNN思路结构框图 MTCNN关键步骤 MTCNN思路结构框图 MTCNN关键步骤 1.Proposal Net 2.Refine Net 3.Out ...
最新文章
- unity人物刚体移动_Unity 刚体移动,自方向移动
- c语言精炼pdf,发计算机二级C语言多年精炼笔试试卷.pdf
- centos 安装指定版本gc_番外篇 (1) Docker 安装
- linux下修改rm命令防止误删除
- 20应用统计考研复试要点(part30)--简答题
- More Effective C++ (运算符)
- 阿里云ECS服务器部署HADOOP集群(三):ZooKeeper 完全分布式集群搭建
- php过滤4字节的字符串,过滤utf8 字符中超过三个字节的字符,或者非utf8字符
- rk3399_android7.1调试USB蓝牙模块小结
- 【HAVENT原创】NodeJS 短网址开发(调用第三方接口)
- android x5内核 下载地址,在Android项目中集成腾讯X5内核
- 蓝牙耳机测试软件apk_Bose Connect(蓝牙耳机控制器)
- 5G核心网-Identifiers身份标识
- win7 快速启动栏 里的快捷方式存放路径
- 建设内链要注意的事项
- vue 项目中 自动生成 二维码
- 实现登录注册页面详细(Servlet+jsp+java)
- 二叉树最强总结(python实现)
- MySQL vs MariaDB
- 12岁“乖乖女”出走后割腕欲轻生 警方3小时全城搜寻