算法导论 练习12.2

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 == NIL
    return x
 return TREE-MINIMUM(x.left);

TREE-MAXIMUM(x)
 if x.right == NIL
    return x
 return TREE-MAXIMUM(x.right)

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

与书上的TREE-SUCCESSOR想对称

TREE-PREDECESSOR
 if x.left != NIL
    return TREE-MAXIMUM(x.left)
 y = x.p
 while y != NIL and y.left == x
    x = y
    y = 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 CaA,bB,cC,一定满足a≤b≤ca \leq b \leq cabc。请给出该教授这个论断的一个最小可能的反例。

在这里插入图片描述
查找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;<prex> ,假如preprepre存在右孩子ppretppretppret,那么在中序遍历时,遍历完成preprepre后接着遍历ppreppreppre,这与之前中序遍历的序列相矛盾。即xxx的前驱preprepre不存在右孩子。同理xxx的后继结点不存在左孩子。


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

证明:
 首先确定yyyxxx的祖先,如果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,因此假设不成立。yyyxxx的祖先得证。
 接下来证明y.lefty.lefty.leftxxx的祖先。假设y.lefty.lefty.left不是xxx的祖先,那么y.righty.righty.right将是xxx的祖先,意味着x&gt;yx &gt; yx>y,矛盾。因此y.lefty.lefty.leftxxx的祖先。
 最后证明yyyxxx的最底层祖先,同时y.lefty.lefty.left也是xxx的祖先。假设yyy不是xxx的最底层祖先但是y.lefty.lefty.leftxxx的祖先,令zzz表示最底层祖先,zzz一定是yyy的左子树,因此有z&lt;yz &lt; yz<y,意味着zzzxxx的后继,矛盾,假设不成立。


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并且该结点没有右孩子。

假设vvvuuu的左孩子

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

假设vvvuuu的右孩子

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,令yyyxxx的第kkk个后继结点,zzzx,yx,yx,y的最底层公共祖先。连续调用TREE-SUCCESSOR类似树的遍历,每条边的遍历次数不超过2次,所以我们不会检查一个结点超过3次。另外,任何结点关键字不是在x,yx,yx,y之间最多检查一次,发生在一条从&lt;x−…−…z&gt;&lt;x-\dotsc-\dotsc z&gt;<xz>&lt;y−…−…−z&gt;&lt;y-\dotsc-\dotsc -z&gt;<yz> (路径)。这些路径的长度由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的最大关键字。

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

目录(Table of Contents)   前言(Preface)   第一部分(Part I) 基础(Foundations)   第一章 计算中算法的角色(The Role of Algorithms in Computing)   第二章 开始(Getting Started)   第三章 函数的增长率(Growth of Functions)   第四章 递归(Recurrences)   第五章 概率分析与随机化算法(Probabilistic Analysis and Randomized Algorithms)   第二部分(Part II) 排序与顺序统计(Sorting and Order Statistics)   第六章 堆排序(Heapsort)   第七章 快速排序(Quicksort)   第八章 线性时间中的排序(Sorting in Linear Time)   第九章 中值与顺序统计(Medians and Order Statistics)   第三部分(Part III) 数据结构(Data Structures)   第十章 基本的数据结构(Elementary Data Structures)   第十一章 散列表(Hash Tables)   第十二章 二叉查找树(Binary Search Trees)   第十三章 红-黑树(Red-Black Trees)   第十四章 扩充的数据结构(Augmenting Data Structures)   第四部分(Part IV) 高级的设计与分析技术(Advanced Design and Analysis Techniques)   第十五章 动态规划(Dynamic Programming)   第十六章 贪婪算法(Greedy Algorithms)   第十七章 分摊分析(Amortized Analysis)   第五部分(Part V) 高级的数据结构(Advanced Data Structures)   第十八章 B-树(B-Trees)   第十九章 二项式堆(Binomial Heaps)   第二十章 斐波纳契堆(Fibonacci Heaps)   第二十一章 不相交集的数据结构(Data Structures for Disjoint Sets)   第六部分(Part VI) 图算法(Graph Algorithms)   第二十二章 基本的图算法(Elementary Graph Algorithms)   第二十三章 最小生成树(Minimum Spanning Trees)   第二十四章 单源最短路径(Single-Source Shortest Paths)   第二十五章 全对的最短路径(All-Pairs Shortest Paths)   第二十六章 最大流(Maximum Flow)   第七部分(Part VII) 精选的主题(Selected Topics)   第二十七章 排序网络(Sorting Networks)   第二十八章 矩阵运算(Matrix Operations)   第二十九章 线性规划(Linear Programming)   第三十章 多项式与快速傅里叶变换(Polynomials and the FFT)   第三十一章 数论算法(Number-Theoretic Algorithms)   第三十二章 字符串匹配(String Matching) ......................................................
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值