uTank-木头
每一个你不满意的现在,都有一个你没有努力的曾经。

二叉树的常见操作实现:

  • 先序遍历、中序遍历、后序遍历层序遍历
  • 由先序序列和中序序列建立二叉树
  • 由后序序列和中序序列建立二叉树
  • 由层序序列和中序序列建立二叉树
  • 求二叉树的叶子结点数
  • 求二叉树的高度
  • 查找值为x的结点
  • 输出二叉树中值为x的节点的所有祖先
  • 输出值为x的结点的所有子孙结点
  • 求二叉树中结点值x的层数
  • 求二叉树第k层的结点个数
  • 求第k层上叶子结点的个数
  • 反转二叉树 将左边的二叉树反转成右边的二叉树

 

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4  
  5 struct node
  6 {
  7     char data;
  8     struct node *lt, *rt;
  9 };
 10 
 11 // 前序遍历
 12 void tree_preorder(struct node *root)
 13 {
 14     if(root)
 15     {
 16         printf("%c", root->data);       
 17         tree_preorder(root->lt);
 18         tree_preorder(root->rt);
 19     }
 20 }
 21 
 22 // 中序遍历
 23 void tree_midorder(struct node *root)
 24 {
 25     if(root)
 26     {
 27         tree_midorder(root->lt);
 28         printf("%c", root->data);          
 29         tree_midorder(root->rt);
 30     }
 31 }
 32 
 33 // 后序遍历
 34 void tree_postorder(struct node *root)
 35 {
 36     if(root)
 37     {
 38         tree_postorder(root->lt);
 39         tree_postorder(root->rt);
 40         printf("%c", root->data);
 41     }
 42 }
 43 
 44 // 层序遍历
 45 void tree_levelorder( struct node *root )
 46 {
 47     struct node *queue[100];
 48     struct node *pt;
 49     int head;
 50     int tail;
 51 
 52     head = 0;
 53     tail = 0;
 54 
 55     queue[tail++] = root;
 56     while( tail != head )
 57     {
 58         pt = queue[head++];
 59         printf("%c", pt->data);
 60         if( pt->lt != NULL )
 61         {
 62             queue[tail++] = pt->lt;
 63         }
 64 
 65         if( pt->rt != NULL )
 66         {
 67             queue[tail++] = pt->rt;
 68         }
 69     }
 70 }
 71 
 72 // 由先序序列和中序序列建立二叉树
 73 struct node *create_by_pre_and_mid(int n, char *pre, char *mid)
 74 {
 75     struct node *root;
 76     int i;
 77 
 78     if(n==0)
 79         return NULL;
 80 
 81     root=(struct node *)malloc(sizeof(struct node));
 82     root->data=pre[0];
 83 
 84     for(i=0;i<n;i++) // 寻找左右子树的元素
 85         if(pre[0]==mid[i])
 86             break;
 87 
 88     root->lt = create_by_pre_and_mid(i, pre+1, mid); // 建立左子树
 89     root->rt = create_by_pre_and_mid(n-i-1, pre+i+1, mid+i+1); // 建立右子树
 90 
 91     return root;
 92 }
 93 
 94 // 由后序序列和中序序列建立二叉树
 95 struct node *create_by_post_and_mid(int n, char *post, char *mid)
 96 {
 97     struct node *root;
 98     int i;
 99 
100     if(n==0)
101         return NULL;
102 
103     root=(struct node *)malloc(sizeof(struct node));
104     root->data=post[n-1];
105 
106     for(i=0;i<n;i++) // 寻找左右子树的元素
107         if(post[n-1]==mid[i])
108             break;
109 
110     root->lt = create_by_post_and_mid(i, post, mid); // 建立左子树
111     root->rt = create_by_post_and_mid(n-i-1, post+i, mid+i+1); // 建立右子树
112 
113     return root;
114 }
115 
116 // 由层序序列和中序序列建立二叉树
117 struct node *create_by_level_and_mid(int n, char *level, char *mid)
118 {
119     struct node *root;
120     char left[30];
121     char right[30];
122     int i, k;
123     int l, r;
124     int lcnt, rcnt;
125 
126     lcnt = 0;
127     rcnt = 0;
128 
129     if( n == 0 )
130         return NULL;
131 
132     root = (struct node *)malloc(sizeof(struct node));
133     root->data = level[0];
134 
135     // 找到根节点
136     for( i = 0; i < n; i++ )
137         if( level[0] == mid[i] )
138             break;
139     
140     // 划分左右子树的层序序列
141     for( k = 0; k < n; k++ )
142     {
143         for( l = 0; l < i; l++ )
144         {
145             if( mid[l] == level[k] )
146             {
147 
148                 left[lcnt++] = level[k];
149             }
150         }
151         for( r = 0; r < n-i-1; r++ )
152         {
153             if( mid[r+i+1] == level[k] )
154             {
155                 right[rcnt++] = level[k];
156             }
157         }
158     }
159 
160     root->lt = create_by_level_and_mid( lcnt, left, mid );
161     root->rt = create_by_level_and_mid( rcnt, right, mid+i+1 );
162 
163     return root;
164 }
165 
166 // 求二叉树的叶子结点数
167 int tree_leaves( struct node *root )
168 {
169     if( root == NULL )
170     {
171         return 0;
172     }
173     else if( root->lt == NULL && root->rt == NULL )
174     {
175         return 1;
176     }
177     else
178     {
179         return ( tree_leaves(root->lt) + tree_leaves(root->rt) );
180     }
181 }
182 
183 // 求二叉树的高度
184 int tree_height( struct node *root )
185 {
186     int lh, rh, max;
187 
188     if( root == NULL )
189     {
190         return 0;
191     }
192     
193     lh = tree_height( root->lt );
194     rh = tree_height( root->rt );
195 
196     max = ( lh > rh ) ? lh : rh;
197 
198     return ( max + 1 );
199 }
200 
201 // 查找值为x的结点
202 struct node *tree_find_x( struct node *root, char x )
203 {
204     struct node *tmp;
205 
206     if( root == NULL )
207         return NULL;
208 
209     if( root->data == x )
210         return root;
211 
212     tmp = tree_find_x( root->lt, x ); // 查找左子树
213     if( tmp != NULL )
214         return tmp;
215 
216     return tree_find_x( root->rt, x ); // 查找右子树
217 }
218 
219 // 输出二叉树中值为x的节点的所有祖先
220 int tree_ancestor( struct node *root, char x )
221 {
222     if( root == NULL )
223     {
224         return 0;
225     }
226     else if( (root->lt != NULL && root->lt->data == x) || (root->rt != NULL && root->rt->data == x) )
227     {
228         // 父结点
229         printf("%c ", root->data);
230         return 1;
231     }
232     else if( tree_ancestor( root->lt, x ) || tree_ancestor( root->rt, x ) )
233     {
234         // 祖先结点
235         printf("%c ", root->data);
236         return 1;
237     }
238     else
239     {
240         return 0;
241     }
242 }
243 
244 // 输出二叉树中值为x的节点的所有祖先
245 // https://blog.csdn.net/u010095372/article/details/83443750
246 int tree_root_of_x( struct node *root, char x )
247 {
248     if( root == NULL )
249         return 0;
250 
251     if( root->data == x )
252         return 1;
253 
254     if( root )
255     {
256         if( tree_root_of_x( root->lt, x ) || tree_root_of_x( root->rt, x ) )
257         {
258             printf("%c ", root->data);
259             return 1;
260         }
261     }
262 
263     return 0;
264 }
265 
266 // 输出值为x的结点的所有子孙结点
267 void tree_child_of_x( struct node *root, char x )
268 {
269     struct node *tmp;
270 
271     tmp = tree_find_x( root, x );
272     if( tmp != NULL )
273     {
274         tree_preorder( tmp->lt );
275         tree_preorder( tmp->rt );
276     }
277 }
278 
279 // 输出值为x的结点的所有子孙结点
280 void tree_child_x( struct node *root, char x )
281 {
282     if( root != NULL )
283     {
284         if( root->data == x )
285         {
286             tree_preorder( root->lt );
287             tree_preorder( root->rt );        
288         }
289         else
290         {
291             tree_child_x( root->lt, x );
292             tree_child_x( root->rt, x );
293         }
294     }
295 }
296 
297 // 求二叉树中结点值x的层数
298 // 返回0表示未找到,根节点的层数为1,h初始置为1
299 int tree_find_x_level( struct node *root, char x, int h )
300 {
301     int level;
302 
303     if( root == NULL )
304         return 0;
305     
306     if( root->data == x )
307         return h;
308 
309     level = tree_find_x_level( root->lt, x, h+1 );
310     if( level != 0 )
311         return level;
312 
313     return tree_find_x_level( root->rt, x, h+1 );
314 }
315 
316 // 求二叉树第k层的结点个数
317 int tree_cnt_of_level_k( struct node *root, int h, int k )
318 {
319     if( root == NULL )
320     {
321         return 0;
322     }
323     else
324     {
325         if( h == k )
326         {
327             return 1;
328         }
329 
330         if( h < k )
331         {
332             return ( tree_cnt_of_level_k( root->lt, h+1, k ) + tree_cnt_of_level_k( root->rt, h+1, k ) );
333         }
334     }
335     return 0;
336 }
337 
338 // 求第k层上叶子结点的个数
339 int tree_leaves_of_level_k( struct node *root, int h, int k )
340 {
341     if( root == NULL )
342     {
343         return 0;
344     }
345     else
346     {
347         if( h == k && root->lt == NULL && root->rt == NULL )
348         {
349             return 1;
350         }
351 
352         if( h < k )
353         {
354             return ( tree_leaves_of_level_k( root->lt, h+1, k ) + tree_leaves_of_level_k( root->rt, h+1, k ) );
355         }
356     }
357     // ( h==k 但是存在左子树或存在右子树 )
358     return 0;
359 }
360 
361 // 反转二叉树 将左边的二叉树反转成右边的二叉树
362 void tree_invert( struct node *root )
363 {
364     struct node *tmp;
365 
366     if( root )
367     {
368         tmp = root->lt;
369         root->lt = root->rt;
370         root->rt = tmp;
371 
372         tree_invert( root->lt );
373         tree_invert( root->rt );
374     }
375 }
376 
377 /**
378  *
379  *           A
380  *          / \
381  *         B   C
382  *        / \ / \ 
383  *       D  E G  H
384  *         /      \
385  *        F        I
386  *
387  *    char *post = "DFEBGIHCA";
388  *    char *pre = "ABDEFCGHI";
389  *    char *mid = "DBFEAGCHI";
390  *    char *level = "ABCDEGHFI";
391  *
392  *
393  *           A
394  *          / \
395  *         B   C
396  *        / \ / \ 
397  *       D  E G  H
398  *         /      \
399  *        F        I
400  *                / \
401  *               J   K
402  *                    \
403  *                     L
404  *
405  *  char *mid = "DBFEAGCHJIKL"
406  *  char *level = "ABCDEGHFIJKL"
407  **/
408 int main( void )
409 {
410     struct node *tmp;
411     struct node *root=NULL;
412     int len;
413     //char *post = "DFEBGIHCA";
414     //char *pre = "ABDEFCGHI";
415     //char *mid = "DBFEAGCHI";
416     //char *level = "ABCDEGHFI";
417 
418     char *mid = "DBFEAGCHJIKL";
419     char *level = "ABCDEGHFIJKL";
420 
421     int leaves;
422     int height;
423     int level_of_x;
424     int x;
425     int cnt_of_level;
426     int leaves_of_level;
427     int k;
428 
429     len = strlen(mid);
430 
431     //root = create_by_pre_and_mid(len, pre, mid);
432     //root = create_by_post_and_mid(len, post, mid);
433     root = create_by_level_and_mid( len, level, mid );
434 
435     printf("tree_preorder: ");
436     tree_preorder(root);
437     printf("\r\n");
438 
439     printf("tree_midorder: ");
440     tree_midorder(root);
441     printf("\r\n");
442 
443     printf("tree_postorder: ");
444     tree_postorder(root);
445     printf("\r\n");
446 
447     printf("tree_levelorder: ");
448     tree_levelorder( root );
449     printf("\r\n");
450 
451 
452     leaves = tree_leaves( root );
453     printf("tree_leaves: %d\r\n", leaves);
454 
455     height = tree_height( root );
456     printf("tree_height: %d\r\n", height);
457 
458 
459     for( k = 1; k <= height; k++ )
460     {
461         cnt_of_level = tree_cnt_of_level_k( root, 1, k );
462         printf("tree_cnt_of_level_k(%d): %d\r\n", k, cnt_of_level);
463     }
464 
465     for( k = 1; k <= height; k++ )
466     {
467         leaves_of_level = tree_leaves_of_level_k( root, 1, k );
468         printf("tree_leaves_of_level_k(%d): %d\r\n", k, leaves_of_level);
469     }
470 
471     for( x = 0; x < 12; x++ )
472     {
473         printf("tree_ancestor(%c):", 'A'+x);
474         tree_ancestor( root, 'A'+x );
475         printf("\r\n");
476     }
477 
478     for( x = 0; x < 12; x++ )
479     {
480         printf("tree_root_of_x(%c):", 'A'+x);
481         tree_root_of_x( root, 'A'+x );
482         printf("\r\n");
483     }
484 
485     for( x = 0; x < 12; x++ )
486     {
487         printf("tree_child_of_x(%c):", 'A'+x);    
488         tree_child_of_x( root, 'A'+x);        
489         printf("\r\n");
490     }
491 
492     for( x = 0; x < 12; x++ )
493     {
494         printf("tree_child_x(%c):", 'A'+x);    
495         tree_child_x( root, 'A'+x);        
496         printf("\r\n");
497     }    
498 
499     for( x = 0; x < 12; x++ )
500     {
501         tmp = tree_find_x( root, 'A'+x );
502         if( tmp )
503         {
504             printf("tree_find_x(%c): %p, %c\r\n", 'A'+x, tmp, tmp->data);
505         }
506         else
507         {
508             printf("tree_find_x( %c ) not found!\r\n", 'A'+x);
509         }
510     }
511 
512     for( x = 0; x < 12; x++ )
513     {
514         level_of_x = tree_find_x_level( root, 'A'+x, 1 );
515         printf("tree_find_x_level(%c): %d\r\n", 'A'+x, level_of_x );
516     }
517 
518 
519     printf("==============================\r\n");
520     tree_invert( root );
521     printf("after tree_invert\r\n");
522 
523     printf("tree_preorder: ");
524     tree_preorder(root);
525     printf("\r\n");
526 
527     printf("tree_midorder: ");
528     tree_midorder(root);
529     printf("\r\n");
530 
531     printf("tree_postorder: ");
532     tree_postorder(root);
533     printf("\r\n");
534 
535     printf("tree_levelorder: ");
536     tree_levelorder( root );
537     printf("\r\n");
538 
539 
540     system("pause");
541     return 0;
542 }

 

 


 

参考:

https://www.cnblogs.com/lfri/p/10256069.html

https://blog.csdn.net/u010095372/article/details/83443750

 

posted on 2019-12-19 10:28  uTank  阅读(565)  评论(0编辑  收藏  举报