12.2-1 假设一棵二叉搜索树中的结点在1到1000之间,现在想要查找值为363得到结点,下面序列那个不是查找过的序列。
a. 2,252,401,398,330,344,397,363。
b. 924,220,911,244,898,258,362,363。
c. 925,202,911,240,912,245,363。
d. 2,399,387,219,266,382,381,278,363。
e. 935,278,347,621,299,392,358,363。
因为这是查找BST过程中的一个序列,因此根据该序列构造BST,如果满足BST的性质,那么就是查找的序列,否则不是。其中c和e不满足。
12.2-2 写出TREE-MINIMUM和TREE-MAXIMUM的递归版本。
1 | //根据书上的版本写的,书中没有判断x是否为空的情况 |
12.2-3 写出过程TREE-PREDECESSOR的伪代码
与书上的TREE-SUCCESSOR想对称
1 | TREE-PREDECESSOR |
12.2-4 Bunyan教授认为他发现了一个二叉搜索树的重要性质。假设在一棵二叉搜索树中查找一个关键字k,查找结束于一个树叶。考虑三个集合:A为查找路径左边的关键字集合;B为u查找路径上的关键字集合;C为查找路径右边的关键字集合。Bunyan教授声称:∀a∈A,b∈B,c∈C,一定满足a≤b≤c。请给出该教授这个论断的一个最小可能的反例。
查找5,那么B={1,4,5},A={2},C={}, 显然不成立。
12.2-5 证明:如果一棵二叉搜索树中一个结点有两个孩子,那么它的后继没有左孩子,它的前驱没有右孩子。
证明:反证法,设结点为x,它的前驱为pre,那么对于BST的中序遍历序列为 <…−pre−x−…> ,假如pre存在右孩子ppret,那么在中序遍历时,遍历完成pre后接着遍历ppre,这与之前中序遍历的序列相矛盾。即x的前驱pre不存在右孩子。同理x的后继结点不存在左孩子。
12.2-6 考虑一棵二叉搜索树T,其关键字互不相同。证明:如果T中一个结点x的右子树为空,且x有一个后继y,那么y一定是x的最底层的祖先,并且左孩子也是x的祖先。(注意到,每个结点都是它自己的祖先。)
证明:
首先确定y是x的祖先,如果y不是x的祖先,设x,y的第一个共同祖先为z,那么根据BST的性质有,x<z<y(因为x没有右子树,那么y只能存在于z的右子树,而x存在于z的左子树,否则就无法满足y为x后继即 x<y的关系),那么x的后继不再是y,因此假设不成立。y为x的祖先得证。
接下来证明y.left是x的祖先。假设y.left不是x的祖先,那么y.right将是x的祖先,意味着x>y,矛盾。因此y.left是x的祖先。
最后证明y是x的最底层祖先,同时y.left也是x的祖先。假设y不是x的最底层祖先但是y.left是x的祖先,令z表示最底层祖先,z一定是y的左子树,因此有z<y,意味着z是x的后继,矛盾,假设不成立。
12.2-7 对于一棵有n个结点的二叉搜索树,有另一个方法实现中序遍历,先调用TREE-MINUMUM找到这棵树中的最小元素,然后再调用n-1次的TREE-SUCCESSOR。证明:该算法的时间复杂度为Θ(n)。
证明:我们要想证明这个边界,其实不难实现,可以通过再TREE-MINIMUM和TREE-SUCCESSOR中统计访问边的次数,对于BST是树,因此满足边的次数=顶点数-1
。不难发现每条边访问次数不超过两次,同时每个顶点需要访问依次,因此时间复杂度为Θ(n)
下面证明对于每一条边最多访问两次:一次从下降(从高到低),一次上升(从低到高)
考虑在树中的一个点u,还有它的孩子v。我们需要先访问从(u,v),才能访问(v,u)。对于下降,只有出现在TREE-MINIMUM,对于上升,只有出现在TREE-SUCCRSSOR并且该结点没有右孩子。
假设v是u的左孩子
在打印u之前,我们需要打印u的左子树,保证下降的遍历边(u,v)
v为根的左子树遍历完成后,打印u。从v为根的左子树的最大结点,调用TREE-SUCCESSOR中,上升遍历边(u,v)。当u的左子树遍历完成后,边(u,v)不再访问。
假设v是u的右孩子
当u打印后,TREE-SUCCESSOR(u)被调用,为了访问v为根的右子树的最小元素,需要下降的遍历边(u,v)。
当u的右子树遍历完成后,v为根的右子树的最大结点,调用的TREE-SUCCRSSOR,上升遍历边(u,v)。当u的右子树遍历完成后,边(u,v)不再访问。
因此,每条边访问次数不会超过2次。时间复杂度为Θ(n)
12.2-8 证明:在一棵高度为h的二叉搜索树中,不论从哪个结点开始,k次连续的TREE-SUCCESSOR调用所需时间为Θ(k+h)。
我们记调用TREE-SUCCESSOR的结点为x,令y为x的第k个后继结点,z为x,y的最底层公共祖先。连续调用TREE-SUCCESSOR类似树的遍历,每条边的遍历次数不超过2次,所以我们不会检查一个结点超过3次。另外,任何结点关键字不是在x,y之间最多检查一次,发生在一条从$
12.2-9 设T是一颗二叉搜索树,其关键字互不相同;设x是一个叶结点,y为其父结点。证明:y.key或者T树中大于x.key的最小关键字,或者是T树中小于x.key的最大关键字。
证明:假设x是y的左孩子,那么x的后继是y,即y.key是T树种大于x.key的最小关键字,若x是y的右孩子,那么y的前驱是x,即y.key是T树小于x.key的最大关键字。