[算法导论 12章练习答案] 12.2 12.3

12.3

12.3
 1 //12.3-1
 2 TREE-INSERT(T,z)
 3     if root[T]=NIL
 4         root[t]=z
 5         return;
 6     x=root[T]
 7     if key(z)<key[x]
 8         TREE-INSERT(left[T],z) // here left[T] is a pointer to a tree, for we may modify the content of the tree
 9     else
10         TREE-INSERT(right[T],z)
11 
12 //12.3-2
13 // 论证:为在树中查找一个key,所检查的节点数等于插入该key时所检查的结点数+1
14 // 论证过程:假设插入该key时检查的结点路径是n0n1n2...nk,则查找该key时的路径也一定是n0n1...nk,不可能有第二条路径。
15 // 再加上该key结点,因此总共要检查k+1个节点数
16 
17 //12.3-3
18 /*
19     最好情况是:nlgn
20     最坏情况: n2
21 */
22 
23 //12.3-4 另外有一种数据结构包含指向BST某结点y的指针。用过程tree-delete删除y的前趋z,这样做会出现什么问题.如何改写tree-delete来解决这些问题
24 /*
25     会出现问题:y的指针失效
26     改写方法:tree-delete中,除了被删除结点的指针,其他结点的指针不变
27 */
28 // original version
29 TREE-DELETE(T,z)
30     if(left[z]=NIL or right[z]=NIL)
31         y=z
32     else
33         y=TREE-SUCCESSOR(z) // y is the node to be delete. and y should have at most one child. Can we use TREE-PREDECESSOR?
34     if left[y]!=NIL
35         x=left[y]
36     else
37         x=right[y]
38     if x!=NIL
39         p[x]=p[y]
40     if p[y]==NIL  // the tree is empty
41         root[T]=x
42     else 
43         if y=left[p[y]]
44             left[p[y]]=x
45         else
46             right[p[y]]=x
47     if y!=z
48         key[z]=key[y]
49         // and copy the satellite data from y to z
50     return y
51     
52 // modified version
53 TREE-DELETE(T,z)
54     if(left[z]=NIL or right[z]=NIL)
55         y=z
56     else
57         y=TREE-SUCCESSOR(z) // y is the node to be delete. and y should have at most one child. Can we use TREE-PREDECESSOR?
58     if left[y]!=NIL
59         x=left[y]
60     else
61         x=right[y]
62     if x!=NIL
63         p[x]=p[y]
64     
65     // 已经删除了要删除的结点
66     if p[y]==NIL  // the tree is empty
67         root[T]=x
68     else 
69         if y=left[p[y]]
70             left[p[y]]=x
71         else
72             right[p[y]]=x
73             
74     if y!=z
75         left[y]=left[z]
76         right[y]=right[z]
77         if z=left[p[z]]
78             left[p[z]]=y
79         else
80             right[p[z]]=y
81     return y
82     
83 //12.3-6
84 //修改策略:如何选择前趋或后继结点作为被拼接的结点,使得有更好的经验性能
85 //假设被删除的结点是z,有两个子节点。其前趋是p,后继是s。则一定有h(z)<h(p),h(z)<h(s)
86 // 从p、s中选择高度较大的结点作为被拼接的结点。这样可减少z的两棵子树的高度差,使得树更加平衡
原文地址:https://www.cnblogs.com/chenhuanfa/p/2794134.html