前言

二叉搜索树(又名二叉查找树、二叉排序树)是一种可提供良好搜寻效率的树形结构,支持动态集合操作,所谓动态集合操作,就是Search、Maximum、Minimum、Insert、Delete等操作,二叉搜索树的基本操作所花费的时间与这棵树的高度成正比。一棵随机构造的二叉搜索树的期望高度为O(lgn),当然,在最坏情况下,即所有节点形成一种链式树结构,则需要O(n)时间。

二叉查找树

设x为二叉查找树中的一个结点。如果y是x的左子树中的一个结点,则key[y]≤key[x]。如果y是x的右子树中的一个结点,则key[x]≤key[y].

二叉搜索树的性质允许我们通过一个简单的递归算法来按序输出二叉搜索树中的所有关键字,这种算法称为中序算法(inorder tree walk)。

INORDER-TREE-WALK(x)if x!=nullINORDER-TREE-WALK(x.left)print x.keyINORDER-TREE-WALK(x.right)
  • 先序遍历(preorder tree walk)中输出的根的关键字在其左右子树的关键字之前
  • 后序遍历(postorder tree walk)输出的根的关键字在其左右子树的关键字值之后

练习

1-1

(略)

1-2 二叉查找树性质与最小堆(见6.1节)之间有什么区别?能否利用最小堆性质在O(n)时间内,按序输出含有n个结点的树中的所有关键字?行的话,解释该怎么做,不行的话,说明原因。

  • 二叉查找树:根的左子树小于根,根的右子树大于根。而最小堆:根的左右子树均大于根。

  • 不能。原因是含有n个结点的最小堆的结点key大小是根<左<右或者根<右<左,左右子树是无序的。导致结果就是不能按照树的前中后序遍历在O(n)时间内来有序的输出他们。

1-3 给出一个非递归的中序树遍历算法。

INORDER-TREE-WALK(T)let S be an empty stackcurrent = T.rootdone = 0while !doneif current != NILPUSH(S, current)current = current.leftelseif !S.EMPTY()current = POP(S)print currentcurrent = current.rightelse done = 1

1-4 对一棵含有n个结点的树,给出能在θ(n)时间内,完成前序遍历和后序遍历的递归算法。

PREORDER-TREE-WALK(x)if x != NILprint x.keyPREORDER-TREE-WALK(x.left)PREORDER-TREE-WALK(x.right)POSTORDER-TREE-WALK(x)if x != NILPOSTORDER-TREE-WALK(x.left)POSTORDER-TREE-WALK(x.right)print x.key

1-5 论证:在比较模型中,最坏情况下排序n个元素的时间为Ω(nlgn),则为从任意的n个元素中构造出一棵二叉查找树,任何一个基于比较的算法在最坏情况下,都要花Ω(nlgn)的时间。

构造二叉查找树的同时也是对一组杂乱无章的数据排序的过程,而基于比较的排序的时间为Ω(nlgn),所以构造这棵树也要Ω(nlgn)。

查询二叉查找树

查询包括查找某一个元素,查找最大、最小关键字元素,查找前驱和后继。根据二叉搜索树的性质:左子树 < 根 < 右子树,这样的操作很容易实现。

#查找
TREE-SEARCH(x, k)if x==null || k==x.keyreturn xif k<x.keyreturn TREE-SEARCH(x.left, k)elsereturn TREE-SEARCH(x.right, k)
#最小关键字元素
TREE-MINIMUM(x)while x.left!=nullx=x.leftreturn x
TREE-MININUM(x)if x.left==nullreturn xelsereturn TREE-MINIMUM(x.left)## 最大关键字元素
TREE-MAXIMUM(x)while x.right!=nullx=x.rightreturn x
TREE-MAXIMUM(x)if x.right==nullreturn xelsereturn MAXIMUM(x.right)
#前驱
TREE-PREDECESSOR(x)if x.left!=nullreturn TREE-MAXIMUM(x.left)y=x.pwhile y!=null and x=y.leftx=yy=y.preturn y#后继
TREE-SUCCESSOR(x)if x.right!=nullreturn TREE-MINIMUM(x.right)y=x.pwhile y!=null and x==y.rightx=yy=y.preturn y

练习

2-1

  • c. 911与912不符合二叉查找树规则。
  • e.347与299不符合二叉查找树规则。

2-2

TREE-MINIMUM(x)if x.left != NILreturn TREE-MINIMUM(x.left)else return xTREE-MAXIMUM(x)if x.right != NILreturn TREE-MAXIMUM(x.right)else return x

2-3

(正文有)

2-4

(略)

2-5

  1. 设这个结点为x其左孩子x1右孩子x2,则有key[x1]≤key[x]≤key[x2]。
  2. 若其后继x2有左子女x3,则key[x3]≤key[x2],而key[x的右子树]≥key[x]
  3. 所以key[x2]≥key[x3]≥key[x],那么x3就为结点x的后继而非x2了

2-6

  1. 若x是其后继y的左孩子,那么key[x]≤key[y],所以y是x的最低祖先,y的左孩子为x的祖先也就是x本身。
  2. 若x是其后继y的右孩子,那么key[x]≥key[y],这明显与后继定义矛盾,y是x的前驱。所以x不可能是后继y的右子树。
  3. 若x是y的左孩子y1的右孩子,那么有key[y1]≤key[x],后继y的左孩子y1是x的祖先,同时y是x的最低祖先。

2-7

通过这n-1结点查后继,每条边至多2次。即O(n)

2-8

每调用一次该函数就需要O(h)时间,调用k次就需要O(kh)时间。这种想法是没有深入分析题目中函数具体调用过程。如果明白12.2-7题目核心内容。就知道,除了第一次调用该函数需要O(h)时间外,其余的连续k-1次遍历了连续的k-1个结点,这k-1个结点有k-2个边,而每条边最多遍历2次。所以总时间T=O(h)+2(k-2)=O(h+k).

2-9

(略)

插入和删除

插入和删除操作会引起由二叉搜索树表示的动态集合的变化,一定要修改数据结构来反映这个变化,但修改要保持二叉搜索树的性质的成立。

插入

指针x记录了一条向下的简单路径,并查找输入项z要进行替换的null(这里隐含的意味也就是z一定是添加作为一个叶结点的)

TREE-INSERT(T, z)y=nullx=T.rootwhile x!=nully=xif z.key<x.keyx=x.leftelsex=x.rightz.p=yif y==nullT.root=zelseif z.key<y.keyy.left=zelsey.right=z

删除

从一棵二叉搜索树T中删除一个结点z的整个策略分为三种基本情况,但只有一种比较棘手:

  • 如果z没有孩子结点,那么只是简单的将它删除,并修改它的父结点,用null作为孩子来替换z;
  • 如果z只有一个孩子,那么将这个孩子提升到树的z的位置上,并修改z的父结点,用z的孩子来替换z;
  • 如果z有两个孩子,那么找z的后继y(一定在z的右子树中),并让y占据树中z的位置。z的原来右子树部分成为y的新的右子树,并且z的左子树成为y的新的左子树。这种情况稍显麻烦,因为还与y是否为z的右孩子相关。
TREE-DELETE(T, z)if z.left==nullTRANSPLANT(T, z, z.right)else if z.right==nullTRANSPLANT(T, z, z.left)else y=TREE-MINIMUM(z.right)TRANSPLANT(T, y, y.right)y.right=z.righty.right.p=yTRANSPLANT(T, x, y)y.left=z.lefty.left.p=yTRANSPLANT(T, u, v)if u.p==nullT.root=velseif u=u.p.leftu.p.left=velseu.p.right=vif v!=nullv.p=u.p

练习

3-1 给出过程TREE-INSERT的一个递归版本

INSERT(p, x, z)if x == NILz.p = pif z.key < p.keyp.left = zelse p.right = zelse if z.key < x.keyINSERT(x, x.left, z)else INSERT(x, x.right, z)RECURSIVE-TREE-INSERT(T, z)if T.root == NILT.root = zelse INSERT(NIL, T.root, z)

3-2 假设我们通过反复插入不同的关键字的做法来构造一棵二叉查找树。论证:为在树中查找一个关键字,所检查的结点数等于插入该关键字时所检查的结点数加1.

从插入和查找函数的while循环遍历结构来看是完全一样的,区别就是查找函数遍历到关键字位置后就结束了,而插入函数遍历到待插入关键字的位置前一个位置便停止遍历转而进行插入工作,所以比查找函数少遍历一个结点。

3-3 可以这样来对n个数进行排序;先构造一棵包含这些数的二叉查找树(重复应用TREE-INSERT来逐个地插入这些数),然后按中序遍历来输出这些数。这个排序算法的最坏情况和最好情况运行时间怎么样?

  • 最坏情况是树的高度为n,此时T(n)=θ(1+2+…+n)+θ(n)=θ(n²)
  • 最好情况是树的高度为h,此时T(n)=θ(lg1+lg2+…lgn)+θ(n)=lgn!+θ(n)=θ(nlgn)

3-4删除操作可交换的吗?(也就是说,先删除x,再删除y的二叉查找树与先删除y再删除x的一样)说明为什么是,或者给出一个反例。

不一样。

  A        C        C/ \      / \        \
B   D    B   D        D/CA        A        D/ \        \      /
B   D        D    C/        /C        C

3-5假设为每个节点换一种设计,将二叉树的parent指针替换为successor指针。试给出使用这种表示法的二叉搜索树T上SEARCH,INSERT和DELETE操作的伪代码。这些伪代码应在O(h)时间内执行完,其中h为T的高度。(提示:应该设计一个返回某个结点的双亲的子过程。)

PARENT(T, x)if x == T.rootreturn NILy = TREE-MAXIMUM(x).succif y == NILy = T.rootelseif y.left == xreturn yy = y.leftwhile y.right != xy = y.rightreturn yINSERT(T, z)y = NILx = T.rootpred = NILwhile x != NILy = xif z.key < x.keyx = x.leftelsepred = xx = x.rightif y == NILT.root = zz.succ = NILelse if z.key < y.keyy.left = zz.succ = yif pred != NILpred.succ = zelsey.right = zz.succ = y.succy.succ = zTRANSPLANT(T, u, v)p = PARENT(T, u)if p == NILT.root = velse if u == p.leftp.left = velsep.right = vTREE-PREDECESSOR(T, x)if x.left != NILreturn TREE-MAXIMUM(x.left)y = T.rootpred = NILwhile y != NILif y.key == x.keybreakif y.key < x.keypred = yy = y.rightelsey = y.leftreturn predDELETE(T, z)pred = TREE-PREDECESSOR(T, z)pred.succ = z.succif z.left == NILTRANSPLANT(T, z, z.right)else if z.right == NILTRANSPLANT(T, z, z.left)elsey = TREE-MIMIMUM(z.right)if PARENT(T, y) != zTRANSPLANT(T, y, y.right)y.right = z.rightTRANSPLANT(T, z, y)y.left = z.left

3-6当TREE-DELETE中的结点z有两个子结点时,可以将其前驱(而不是后继)拼接掉。有些人提出一种公平的策略,即为前驱和后继结点赋予相同的优先级,从而可以得到更好的经验性能。那么,应如何修改TREE-DELETE来实现这样一种公平策略?

(略)

随机构建二叉搜索树

。。

主要参考

《算法导论第十二(12)章 二叉查找树》
《Binary Search Trees》
《算法导论第十二章 二叉搜索树》

《算法导论3rd第十二章》二叉查找树相关推荐

  1. 数据结构--二叉查找树 Binary Search Tree

    文章目录 1.二叉查找树概念 2.二叉查找树操作 2.1 查找 2.2 插入 2.3 删除 2.4 其他 3. 支持重复数据的二叉查找树 4 有散列表了,还需要二叉查找树? 5 代码实现 1.二叉查找 ...

  2. c#数据结构———二叉查找树

    using System;<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ...

  3. 学习数据结构 二叉查找树(binary search tree)

    2019独角兽企业重金招聘Python工程师标准>>> 为学习 LLVM 的 ImmutableSet,其底层的实现选择为 AVL 树(平衡二叉搜索树),我不很熟悉该树,虽然大致知道 ...

  4. Python数据结构————二叉查找树的实现

    对于二叉查找树的每个节点Node,它的左子树中所有的关键字都小于Node的关键字,而右子树中的所有关键字都大于Node的关键字. 二叉查找树的平均深度是O(log N). 1.初始化 class Bi ...

  5. 数据结构|-二叉查找树(二叉搜索树)的链式存储结构的实现

    二叉排序树,又称为二叉查找树. 它或者是一棵空树,或者是具有下列性质的二叉树. 若它的左子树不为空,则左子树上所有的结点的值均小于根结构的值: 若它的右子树不为空,则右字数上所有结点的值均大于它的根结 ...

  6. 数据结构——二叉查找树(BST)的删除

    数据结构--二叉树(BST)的删除 文章目录 数据结构--二叉树(BST)的删除 前言 一.BST删除的几种情况 二.节点删除方法 1.一般方法 2.对1方法的优化 3.懒汉删除(前继和后继) 前言 ...

  7. 数据库底层设计(MYSQL索引的数据结构)

    前言 说到数据库这个词,我只能用爱恨交加这个词来形容它.自己之前还单纯懵懂的时候进了数据库的课堂,听完数据库的课,觉得这是一门再简单不过的课程,任何一门编程语言都比SQL要晦涩难懂,任何一门理论课程都 ...

  8. MySQL底层为什么要选用B+树作为索引的数据结构呢?

    文章目录 MySQL底层为什么要选用B+树作为索引的数据结构呢? MySQL 索引底层数据结构选型 哈希表(Hash) 二叉查找树(BST) 平衡二叉树(AVL树) 红黑树 B-树 B+树 参考 My ...

  9. MySQL(三)MySQL索引原理

    数据库索引,是数据库管理系统(DBMS)中一个排序的数据结构,以协助快速查询.更新数据库表中数据.                                                    ...

  10. [转载] --- 数据库基本知识

    里面的很多点,我之前都总结过,但是感觉这篇把这些都连起来了,总结的挺好,转载保存一下 [从入门到入土]令人脱发的数据库底层设计 前言 说到数据库这个词,我只能用爱恨交加这个词来形容它.两年前在自己还单 ...

最新文章

  1. PSVR周年庆开始,大量游戏巨幅促销
  2. android 键盘搜索按钮不收起键盘,android EditText 实现搜索框点击搜索隐藏键盘
  3. Ubuntu下mysql中文乱码的解决
  4. awk打印第一个字母
  5. 【struts2】struts2配置文件—struts.properties
  6. 类文件结构-访问标识和继承信息
  7. 转换uptime_句型转换
  8. 11月22日云栖精选夜读 | 送你一份Spring Boot 知识清单
  9. bat批处理命令详解
  10. SpringMVC课堂笔记
  11. 推荐一个php Zend Guard解密工具 G-DeZender 本地版
  12. win10去除右下角激活水印
  13. 玩安卓从 0 到 1 之总体概览
  14. ios键盘横屏_iOS 强制横屏、部分横屏等功能实践
  15. 彩色rgb图像拆分为rgb三个通道,并重新合并为彩色图像
  16. 为什么说智能传感器必将引领时代前行?
  17. 国内国际期货,外汇,现货跟单、量化交易系统
  18. python爬取pbf格式的矢量瓦片并转换为shp使用
  19. 关于5G无人机的最强科普
  20. C#与.NET程序员面试宝典 2.1.6 面试题6:C#中的托管代码是什么

热门文章

  1. python 人物关系图_python简单实战项目:《冰与火之歌1-5》角色关系图谱构建——人物关系可视化...
  2. 前端学习笔记之页面制作(一)——PS切图
  3. 基于Forest实践|如何更优雅的统一处理请求签名
  4. word中标题去掉前面的点
  5. X1000对于音频播放控制部分的翻译
  6. atsc-m/h现状
  7. 微信图片怎么添加竖排文字_微信拍照的照片怎样加文字?
  8. axi_ddr_top
  9. 隐藏计算机关机键,关机快捷键有哪些?电脑Windows快捷关机最全方法图文详解
  10. 中国智慧消防产业需求现状及十四五发展趋向分析报告2021-2027年版