二叉树操作

二叉树操作

实验目的

实现如下二叉树操作,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 }
View Code

 

posted @ 2018-08-30 11:56  JayInnn  阅读(208)  评论(0编辑  收藏  举报