二叉树操作
二叉树操作
实验目的
实现如下二叉树操作,Input:1-n的数组
(1)通过插入操作建立二叉树
(2)实现查找、最大/小关键字查询
(3)从1到n的依次删除
实验原理
二叉搜索树上的基本操作所花费的时间与这棵树的高度成正比。二叉搜索树可以使用一个链表数据结构来表示,其中每个结点都是一个对象。每个结点包含属性key,left,right,p,它们分别指向结点的关键字,左孩子,右孩子和双亲。如果某个孩子结点和父亲结点不存在,则相应属性值为NIL。
二叉搜索树中关键字满足二叉搜索树性质:设x是二叉搜索树中的一个结点,如果y是x左子树中的一个结点,那么y.key <= x.key;如果y是x右子树中的一个结点,那么y.key >= x.key。
实验过程
(一)插入法建立二叉树
要将一个新值v插入到一棵二叉搜索数T中,需要调用过程TREE-INSERT。该过程以结点z作为输入,其中z.key = v, z.left = NIL, z.right = NIL。
TREE-INSERT(T, z)
1 y = NIL
2 x = T.root
3 while x != NIL
4 y = x
5 if z.key < x.key
6 x = x.left
7 else x = x.right
8 z.p = y
9 if y == NIL
10 T.root = z
11 elseif z.key < y.key
12 y.left = z
13 else y.right = z
(二)实现查找、最大/小关键字查询
查找:输入一个指向树根的指针和一个关键字k,如果这个结点存在,TREE-SEARCH返回一个指向关键字k的节点的指针;否则返回NIL。
TREE-SEARCH(x, k)
1 if x == NIL or k == x.key
2 return x
3 if k < x.key
4 return TREE-SEARCH(x.left, k)
5 else return TREE-SEARCH(x.right, k)
最大关键字元素和最小关键字元素:通过从树根开始沿着left孩子指针直到遇到一个NIL,返回一个指向在以给定结点x为根的子树中的最小元素的指针;通过从树根开始沿着right孩子指针直到遇到一个NIL,返回一个指向在以给定结点x为根的子树中的最小元素的指针。
TREE-MINIMUM(x)
1 while x.left != NIL
2 x = x.left
3 return x
TREE-MAXIMUM(x)
1 while x.right != NIL
2 x = x.right
3 return x
(三)实现删除
从一棵二叉搜索树T中删除一个结点z的整个策略分为三种基本情况:
1)如果z没有孩子结点,那么只是简单地将它删除,并修改它的父结点,孩子结点指向NIL;
2)如果z只有一个孩子,那么将这个孩子提升到树中z的位置上,用z的孩子来替换z;
3)如果z有两个孩子,那么先找到z的后继结点y,如果y是z的右孩子,那么用y替换z,并仅留下y的右孩子;如果,y位于z的右子树中但并不是z的右孩子,先用y的右孩子替换y,然后再用y替换z;
定义一个过程TRANSPLANT,它是用另一棵子树替换一棵子树并成为其双亲的孩子结点:
TRANSPLANT(T, u, v)
1 if u.p == NIL
2 T.root = v
3 elseif u == u.p.left
4 u.p.left = v
5 else u.p.right = v
6 if v != NIL
7 v.p = u.p
TREE-DELETE(T, z)
1 if z.left == NIL
2 TRANSPLANT(T, z, z.right)
3 elseif z.right == NIL
4 TRANSPLANT(T, z, z.left)
5 else y = TREE-MINIMUM(z.right)
6 if y.p != z
7 TRANSPLANT(T, y, y.right)
8 y.right = z.right
9 y.right.p = y
10 TRANSPLANT(T, z, y)
11 y.left = z.left
12 y.left.p = y
实验总结
(一)二叉搜索树优点在于,在树上的基本操作与这棵树的高度成正比:对于一棵有n个结点的完全二叉树,在树上操作的最坏运行时间是Θ(lgn)。然而,如果树是一条n个结点组成的线性链,那么同样的操作就要花费Θ(n)的最坏运行时间。
(二)针对在构建树的过程中,出现最坏情况导致线性链的发生,可采取几种处理方式:可通过随机构建二叉搜索树;还可以设计二叉树的变体,即红黑树,红黑树的树高为O(lgn);还可以使用B树。
(三)二叉搜索树是学习树的基础,为了充分利用二叉搜索树的优点,避免二叉树的最坏情况,从而研究出来了红黑树和B树。
附录(代码)
1 #include <stdio.h> 2 3 #include <stdlib.h> 4 5 6 7 typedef struct node *tree_pointer; 8 9 typedef struct node{ 10 11 int key; 12 13 tree_pointerp; 14 15 tree_pointerleft; 16 17 tree_pointerright; 18 19 } *tree_pointer; 20 21 22 23 void tree_insert(tree_pointer z); 24 25 void print_tree(tree_pointer T_root, int n); 26 27 void transplant(tree_pointer T_root, tree_pointer u,tree_pointer v); 28 29 void tree_delete(tree_pointer T_root, tree_pointer z); 30 31 struct node * creat_node(int key); 32 33 struct node * tree_search(tree_pointer T_root, intkey); 34 35 struct node * tree_minimum(tree_pointer T_root); 36 37 struct node * tree_maximum(tree_pointer T_root); 38 39 int get_tree_height(tree_pointer T_root); 40 41 42 43 tree_pointer T_Root = NULL; 44 45 46 47 int main(){ 48 49 50 51 inti,key,node_number,tree_height,search_key,delete_key; 52 53 54 55 tree_pointernew=NULL; 56 57 tree_pointersearch_result; 58 59 tree_pointerminimum; 60 61 tree_pointermaximum; 62 63 tree_pointerdelete; 64 65 66 67 printf("pleaseinput the number of nodes:"); 68 69 scanf("%d",&node_number); 70 71 for(i = 0; i< node_number; i++ ){ 72 73 printf("inputthe key:"); 74 75 scanf("%d",&key); 76 77 new =creat_node(key); 78 79 tree_insert(new); 80 81 tree_height= get_tree_height(T_Root); 82 83 print_tree(T_Root,tree_height); 84 85 } 86 87 printf("thefinal tree:\n"); 88 89 tree_height =get_tree_height(T_Root); 90 91 print_tree(T_Root,tree_height); 92 93 94 95 printf("\n"); 96 97 minimum =tree_minimum(T_Root); 98 99 maximum =tree_maximum(T_Root); 100 101 printf("Inthis tree, the minimum number is:"); 102 103 printf("%d\n",minimum->key); 104 105 printf("Inthis tree, the maximum number is:"); 106 107 printf("%d\n",maximum->key); 108 109 110 111 printf("\n"); 112 113 printf("whichkey do you want to search?\nplease input it:"); 114 115 scanf("%d",&search_key); 116 117 printf("thesearching result: "); 118 119 search_result= tree_search(T_Root, search_key); 120 121 printf("(%p)and this (%p) refers to %d\n",search_result,search_result,search_result->key); 122 123 124 125 printf("\n"); 126 127 printf("pleaseinput the node that you want to delete:"); 128 129 scanf("%d",&delete_key); 130 131 printf("delete_key= %d\n",delete_key); 132 133 delete =tree_search(T_Root, delete_key); 134 135 printf("wewill delete:(%p) and it refers to %d\n", delete,delete->key); 136 137 printf("deletethe node and print the tree:\n"); 138 139 tree_delete(T_Root,delete); 140 141 tree_height =get_tree_height(T_Root); 142 143 print_tree(T_Root,tree_height); 144 145 return 0; 146 147 } 148 149 150 151 void tree_insert(tree_pointer z){ 152 153 tree_pointerx; 154 155 tree_pointery = NULL; 156 157 x = T_Root; 158 159 160 161 while(x !=NULL){ 162 163 y = x; 164 165 if(z->key< x->key) 166 167 x =x->left; 168 169 else 170 171 x =x->right; 172 173 } 174 175 z->p = y; 176 177 if(y == NULL) 178 179 T_Root = z; 180 181 elseif(z->key < y->key) 182 183 y->left = z; 184 185 else 186 187 y->right= z; 188 189 190 191 } 192 193 194 195 void print_tree(tree_pointer T_root, int n){ 196 197 int i; 198 199 if(T_root ==NULL) 200 201 return; 202 203 print_tree(T_root->right,n-1); 204 205 206 207 for(i = 0; i< n-1; i++) 208 209 printf(" "); 210 211 if(n > 0){ 212 213 printf("---"); 214 215 printf("%d\n",T_root->key); 216 217 } 218 219 220 221 print_tree(T_root->left,n-1); 222 223 } 224 225 226 227 struct node * creat_node(int key){ 228 229 tree_pointernew; 230 231 new = (structnode *)malloc(sizeof(struct node)); 232 233 new->key = key; 234 235 return new; 236 237 } 238 239 240 241 int get_tree_height(tree_pointer T_root){ 242 243 if(!T_root) 244 245 return 0; 246 247 intleft_height,right_height; 248 249 left_height = get_tree_height(T_root->left); 250 251 right_height= get_tree_height(T_root->right); 252 253 return(left_height < right_height)?(right_height+1):(left_height+1); 254 255 } 256 257 258 259 struct node * tree_search(tree_pointer T_root, intkey){ 260 261 while((T_root!= NULL) && (key != T_root->key)){ 262 263 if(key< T_root->key) 264 265 T_root= T_root->left; 266 267 else 268 269 T_root= T_root->right; 270 271 } 272 273 returnT_root; 274 275 } 276 277 278 279 struct node * tree_minimum(tree_pointer T_root){ 280 281 while(T_root->left!= NULL) 282 283 T_root =T_root->left; 284 285 returnT_root; 286 287 } 288 289 290 291 struct node * tree_maximum(tree_pointer T_root){ 292 293 while(T_root->right!= NULL) 294 295 T_root =T_root->right; 296 297 returnT_root; 298 299 } 300 301 302 303 void transplant(tree_pointer T_root, tree_pointer u,tree_pointer v){ 304 305 if(u->p ==NULL) 306 307 T_root =v; 308 309 else if(u ==u->p->left) 310 311 u->p->left = v; 312 313 else 314 315 u->p->right= v; 316 317 if(v != NULL) 318 319 v->p =u->p; 320 321 } 322 323 324 325 void tree_delete(tree_pointer T_root, tree_pointer z){ 326 327 tree_pointery=NULL; 328 329 330 331 if(z->left== NULL) 332 333 transplant(T_root,z , z->right); 334 335 elseif(z->right == NULL) 336 337 transplant(T_root,z , z->left); 338 339 else{ 340 341 y =tree_minimum(z->right); 342 343 if(y->p!= z){ 344 345 transplant(T_root,y , y->right); 346 347 y->right = z->right; 348 349 y->right->p= y; 350 351 } 352 353 transplant(T_root, z , y); 354 355 y->left = z->left; 356 357 y->left->p= y; 358 359 } 360 361 }