007's Studio.

算法导论练习12.3

字数统计: 1.1k阅读时长: 4 min
2019/08/12 Share

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//实现1
TREE-INSERT(T,z)
if T.root = NIL //空树
T.root = z
z.p = NIL
else //非空,递归查找合适位置
TREE-INSERT-RECURSIVE(T.root,z)

TREE-INSERT-RECURSIVE(x,z)
if z.key < x.key
if x.left = NIL
x.left = z
z.p = x
else
TREE-INSERT-RECURSIVE(x.left,z)
else
if x.right = NIL
x.right = z
z.p = x
else
TREE-INSERT-RECURSIVE(x.right,z)

//实现2
//调用 TREE-INSERT-CURSIVE(NIL,T.root,z)
// y为父节点,x为插入位置
TREE-INSERT-CURSIVE(y,x,z)
if x != NIL
if z.key < x.key
TREE-INSERT-CURSIVE(x,x.left,z)
return
else
TREE-INSERT-CURSIVE(x,x.right,z)
return
z.p = y
if y == NIL
T.root = z
else if z.key < y.key
y.left = z
else
y.right = z

12.3-2 假设通过反复向一棵树中插入互不相同的关键字来构造一棵二叉搜索树。证明:在这棵树中查找关键字所检查过的结点数目等于先前插入这个关键字所检查的结点数目加1。

证明:根据书中TREE-INSERT的算法,我们插入一个结点,从根节点开始,判断合适位置插入。再次查找它时,我们沿着之前插入时判断的结点的路径(新插入的结点不会出现在该路径上,因此路径相同),最后再多检查结点本身,因此次数+1。


12.3-3 对于给定$n$个关键字集合,可以通过先构造包含这些数据的一颗二叉搜索树(反复使用TREE-INSERT逐个插入这些数),然后按中序遍历输出这些数的方法,来对它们排序。这个排序算法的最坏情况运行时间和最好情况运行时间各是多少?

最坏情况下是BST的高度为$n$,即按已经排序的方式插入。此时运行时间为$\Theta(n^2)$。在最佳情况下,BST的形状是平衡的,意味着它的高度不超过$O(lgn)$。此时运行时间为$O(nlgn)$,在题目12.1-5中已经说明最坏情况的需要$\Omega(nlgn)$。


12.3-4 删除操作可交换吗?可交换的含义是,先删除$x$再删除$y$留下的结果树与先删除$y$再删除$x$留下的结果树完全一样。如果是,说明为什么?否则,给出一个反例。

不可以交换,反例如下:

先删除1,再删除2,不同于先删除2,再删除1


12.3-5 假设为每个结点换一种设计,属性$x.p$指向父亲,属性$x.succ$指向$x$的后继。给出使用这种表示法的二叉搜索树$T$上SEARCH、INSERT和DELETE操作的伪代码。这些伪代码再$O(h)$时间内执行完,其中$h$为$T$的高度。(提示:应该设计一个返回某个结点的双亲的子过程)。

未解决。有好的想法的可以私我。


12.3-6 当TREE-DELETE中的结点$z$有两个孩子时,应该选择结点$y$作为它的前驱,而不是作为它的后继。如果这样做,对TREE-DELETE应该做哪些什么必要的修改?一些人提出了一个公平的策略,为前驱和后继赋予相等的优先级,这样得到了较好的实验性能。如何对TREE-DELETE进行修改来实现这样一种公平策略?

第一个问题:如果转换成删除前驱,只需要在TREE-DELETE中将有两个孩子的情况修改。

下面是我的伪代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
TREE-DELETE(T,z)
if z.left == NIL
TRANSPLANT(T,z,z.right)
else if z.right == NIL
TRANSPLANT(T,z,z.left)
else y = TREE-MAXIMUM(z.left)
if y.p != z
TRANSPLANT(T,y,y.left)
y.left = z.left
y.left.p = y
TREESPLANT(T,z,y)
y.right = z.right
y.right.p = y

第二个问题:要实现前驱后继相等的优先级,当有两个孩子时,可以采用一个随机数来决定采用前驱替换还是后继替换。

1
2
3
4
5
6
7
8
9
10
11
TREE-DELETE(T,z)
if z.left == NIL
TRANSPLANT(T,z,z.right)
else if z.right == NIL
TRANSPLANT(T,z,z.left)
else
LorR = getRandomBool
if LorR == true
。。。//替换后继
else
。。。//替换前驱

原文作者:007havegone

原文链接:http://007havegone.github.io/2019/08/12/算法导论练习12-3/

发表日期:August 12th 2019, 1:53:18 pm

更新日期:August 12th 2019, 6:01:08 pm

版权声明:‘原创内容,转载时请附上出处’

CATALOG