12.2-1 假设一棵二叉搜索树中的结点在1到1000之间,现在想要查找值为363得到结点,下面序列那个不是查找过的序列。

a. 2,252,401,398,330,344,397,3632,252,401,398,330,344,397,3632,252,401,398,330,344,397,363。
b. 924,220,911,244,898,258,362,363924,220,911,244,898,258,362,363924,220,911,244,898,258,362,363。
c. 925,202,911,240,912,245,363925,202,911,240,912,245,363925,202,911,240,912,245,363。
d. 2,399,387,219,266,382,381,278,3632,399,387,219,266,382,381,278,3632,399,387,219,266,382,381,278,363。
e. 935,278,347,621,299,392,358,363935,278,347,621,299,392,358,363935,278,347,621,299,392,358,363。

因为这是查找BST过程中的一个序列,因此根据该序列构造BST,如果满足BST的性质,那么就是查找的序列,否则不是。其中c和e不满足。


12.2-2 写出TREE-MINIMUM和TREE-MAXIMUM的递归版本。

//根据书上的版本写的,书中没有判断x是否为空的情况
TREE-MINIMUM(x)if x.left == NILreturn xreturn TREE-MINIMUM(x.left);TREE-MAXIMUM(x)if x.right == NILreturn xreturn TREE-MAXIMUM(x.right)

12.2-3 写出过程TREE-PREDECESSOR的伪代码

与书上的TREE-SUCCESSOR想对称

TREE-PREDECESSORif x.left != NILreturn TREE-MAXIMUM(x.left)y = x.pwhile y != NIL and y.left == xx = yy = y.p
return y

12.2-4 Bunyan教授认为他发现了一个二叉搜索树的重要性质。假设在一棵二叉搜索树中查找一个关键字kkk,查找结束于一个树叶。考虑三个集合:AAA为查找路径左边的关键字集合;BBB为u查找路径上的关键字集合;CCC为查找路径右边的关键字集合。Bunyan教授声称:∀a∈A,b∈B,c∈C\forall a \in A,b \in B, c \in C∀a∈A,b∈B,c∈C,一定满足a≤b≤ca \leq b \leq ca≤b≤c。请给出该教授这个论断的一个最小可能的反例。


查找5,那么B={1,4,5},A={2},C={}B=\{1,4,5\},A=\{2\},C=\{\}B={1,4,5},A={2},C={}, 显然不成立。


12.2-5 证明:如果一棵二叉搜索树中一个结点有两个孩子,那么它的后继没有左孩子,它的前驱没有右孩子。

证明:反证法,设结点为xxx,它的前驱为preprepre,那么对于BST的中序遍历序列为 &lt;…−pre−x−…&gt;&lt;\dotsc-pre-x-\dotsc&gt;<…−pre−x−…> ,假如preprepre存在右孩子ppretppretppret,那么在中序遍历时,遍历完成preprepre后接着遍历ppreppreppre,这与之前中序遍历的序列相矛盾。即xxx的前驱preprepre不存在右孩子。同理xxx的后继结点不存在左孩子。


12.2-6 考虑一棵二叉搜索树TTT,其关键字互不相同。证明:如果TTT中一个结点xxx的右子树为空,且xxx有一个后继yyy,那么yyy一定是xxx的最底层的祖先,并且左孩子也是xxx的祖先。(注意到,每个结点都是它自己的祖先。)

证明:
 首先确定yyy是xxx的祖先,如果yyy不是xxx的祖先,设x,yx,yx,y的第一个共同祖先为zzz,那么根据BST的性质有,x&lt;z&lt;yx &lt; z &lt; yx<z<y(因为x没有右子树,那么y只能存在于z的右子树,而x存在于z的左子树,否则就无法满足y为x后继即 x<y的关系),那么xxx的后继不再是yyy,因此假设不成立。yyy为xxx的祖先得证。
 接下来证明y.lefty.lefty.left是xxx的祖先。假设y.lefty.lefty.left不是xxx的祖先,那么y.righty.righty.right将是xxx的祖先,意味着x&gt;yx &gt; yx>y,矛盾。因此y.lefty.lefty.left是xxx的祖先。
 最后证明yyy是xxx的最底层祖先,同时y.lefty.lefty.left也是xxx的祖先。假设yyy不是xxx的最底层祖先但是y.lefty.lefty.left是xxx的祖先,令zzz表示最底层祖先,zzz一定是yyy的左子树,因此有z&lt;yz &lt; yz<y,意味着zzz是xxx的后继,矛盾,假设不成立。


12.2-7 对于一棵有nnn个结点的二叉搜索树,有另一个方法实现中序遍历,先调用TREE-MINUMUM找到这棵树中的最小元素,然后再调用n-1次的TREE-SUCCESSOR。证明:该算法的时间复杂度为Θ(n)\Theta(n)Θ(n)。

证明:我们要想证明这个边界,其实不难实现,可以通过再TREE-MINIMUM和TREE-SUCCESSOR中统计访问边的次数,对于BST是树,因此满足边的次数=顶点数-1。不难发现每条边访问次数不超过两次,同时每个顶点需要访问依次,因此时间复杂度为Θ(n)\Theta(n)Θ(n)

下面证明对于每一条边最多访问两次:一次从下降(从高到低),一次上升(从低到高)

考虑在树中的一个点uuu,还有它的孩子vvv。我们需要先访问从(u,v)(u,v)(u,v),才能访问(v,u)(v,u)(v,u)。对于下降,只有出现在TREE-MINIMUM,对于上升,只有出现在TREE-SUCCRSSOR并且该结点没有右孩子。

假设vvv是uuu的左孩子

在打印uuu之前,我们需要打印uuu的左子树,保证下降的遍历边(u,v)(u,v)(u,v)
vvv为根的左子树遍历完成后,打印uuu。从vvv为根的左子树的最大结点,调用TREE-SUCCESSOR中,上升遍历边(u,v)。当uuu的左子树遍历完成后,边(u,v)(u,v)(u,v)不再访问。

假设vvv是uuu的右孩子

当uuu打印后,TREE-SUCCESSOR(u)被调用,为了访问vvv为根的右子树的最小元素,需要下降的遍历边(u,v)(u,v)(u,v)。

当uuu的右子树遍历完成后,vvv为根的右子树的最大结点,调用的TREE-SUCCRSSOR,上升遍历边(u,v)(u,v)(u,v)。当uuu的右子树遍历完成后,边(u,v)(u,v)(u,v)不再访问。

因此,每条边访问次数不会超过2次。时间复杂度为Θ(n)\Theta(n)Θ(n)


12.2-8 证明:在一棵高度为hhh的二叉搜索树中,不论从哪个结点开始,kkk次连续的TREE-SUCCESSOR调用所需时间为Θ(k+h)\Theta(k+h)Θ(k+h)。

我们记调用TREE-SUCCESSOR的结点为xxx,令yyy为xxx的第kkk个后继结点,zzz为x,yx,yx,y的最底层公共祖先。连续调用TREE-SUCCESSOR类似树的遍历,每条边的遍历次数不超过2次,所以我们不会检查一个结点超过3次。另外,任何结点关键字不是在x,yx,yx,y之间最多检查一次,发生在一条从&lt;x−…−…z&gt;&lt;x-\dotsc-\dotsc z&gt;<x−…−…z>或&lt;y−…−…−z&gt;&lt;y-\dotsc-\dotsc -z&gt;<y−…−…−z> (路径)。这些路径的长度由yyy限制,因此最坏情况时间复杂度为3k+2h=O(k+h)3k+2h=O(k+h)3k+2h=O(k+h)。


12.2-9 设TTT是一颗二叉搜索树,其关键字互不相同;设xxx是一个叶结点,yyy为其父结点。证明:y.keyy.keyy.key或者TTT树中大于x.keyx.keyx.key的最小关键字,或者是TTT树中小于x.keyx.keyx.key的最大关键字。

证明:假设xxx是yyy的左孩子,那么xxx的后继是yyy,即y.keyy.keyy.key是TTT树种大于x.keyx.keyx.key的最小关键字,若xxx是yyy的右孩子,那么yyy的前驱是xxx,即y.keyy.keyy.key是TTT树小于x.keyx.keyx.key的最大关键字。

算法导论 练习12.2相关推荐

  1. 二叉搜索树的查询操作《算法导论》12.2

    我们可以在O(h)时间内完成二叉搜索树的查找.最大值.最小值.给定节点的前驱.后继操作,h代表树的高度.下面是用C++实现的<算法导论>12.2节伪代码,附习题解答. #include & ...

  2. 算法导论 练习12.1

    12.1-1 对于关键字集合{1,4,5,10,16,17,21}\{1,4,5,10,16,17,21\}{1,4,5,10,16,17,21},分别画出高度为2.3.4.5和6的二叉搜索树. 这里 ...

  3. 算法导论 练习12.3

    12.3-1 给出TREE-INSERT过车过程的一个递归版本 //实现1 TREE-INSERT(T,z)if T.root = NIL //空树T.root = zz.p = NILelse // ...

  4. 算法导论——lec 12 平摊分析与优先队列

    在平摊分析中,运行一系列数据结构操作所须要的时间是通过对运行的全部操作求平均得出.反映在不论什么情况下(即最坏情况下),每一个操作具有平均性能.掌握了平摊分析主要有三种方法,聚集分析.记账方法.势能方 ...

  5. 算法导论6.1-2习题解答

    CLRS 6.1-2 : 证明:含n个元素的堆的高度为[lgn]. 证明:因为 2^h <= n <= 2^(h+1) - 1 所以 lg(n+1) -1 <= h<= lg( ...

  6. 算法导论2.1-2.3 部分答案

    习题2.1.2 #include <iostream>using namespace std; void insectionSort(int a[],int len) {for(int i ...

  7. 算法导论练习 10.4-5及12.1-3

    //算法导论10.4-5及12.1-3 //1. 10.4-5 //给定一个n节点的二叉树,写出一个O(n)时间的非递归过程,将该树每个节点的关键 //字输出.要求除该树本身的存储空间外只能使用固定量 ...

  8. 给出TREE_INSERT过程的非递归版本(算法导论第三版12.3-1)

    给出TREE_INSERT过程的非递归版本(算法导论第三版12.3-1) template<typename T> void insert_recursive(BinaryTree< ...

  9. 写出TREE-PREDECESSOR的伪代码(算法导论第三版12.2-3)

    写出TREE-PREDECESSOR的伪代码(算法导论第三版12.2-3) TREE-PREDECESSOR(x)if x.left != NILreturn TREE-MAXIMUM(x.left) ...

最新文章

  1. 云时代服务器端工程师必备 CDN 技能包
  2. AOP代理配置pointcut
  3. wiretiger引擎支持行、列存储、LSM,mongodb用的哪个?
  4. python之路_django路由配置及模板
  5. Spring boot访问静态资源
  6. agile organization
  7. Virtaulbox虚拟机添加磁盘
  8. Linux下启动tomcat报java.lang.OutOfMemoryError: PermGen space
  9. mysql 部署到服务器_服务器快速部署--使用Docker部署MySQL
  10. MyBatis使用log4j输出日志
  11. 计算机网络—计算机网络核心
  12. 云计算的高增长将持续推动光模块行业景气度
  13. StretchDIBits绘制原始YUV异常
  14. python实现 stft_Python中可转换的STFT和ISTFT
  15. 如何提升邮箱邮件安全性,邮箱管理制度有哪些?
  16. wfp 禁用ip_Win64 驱动内核编程-16.WFP网络监控驱动(防火墙)
  17. 【Java+JSP+MySql】12306购票系统(五)购买车票
  18. 赵小楼《天道》《遥远的救世主》深度解析(77)叶、冯、刘三人用了丁元英,就用了他的一切,没有能力的时候还谈什么缘,攀缘没有对错,起码得先活着
  19. GPU在高性能仿真计算中的应用
  20. 焱融看|混合云环境下,如何实现数据湖最优存储解决方案

热门文章

  1. a:link a:visited a:hover a:active四种伪类选择器的区别
  2. 解决kali linux找不到更新的问题
  3. 转换运行时获取DTP语义组
  4. Spring3 工具类大汇集
  5. 关于如何在同一个浏览器用不同的session登录同个系统
  6. oracle的序列为什么会出错,Oracle系列:(24)序列
  7. [Asp.net]Uploadify上传大文件,Http error 404 解决方案 - wolfy
  8. Socket编程总结—Android手机服务器与多个Android手机客户端之间的通信(非阻塞)
  9. Apache性能诊断与调优
  10. 用C#实现屏幕键盘!