zoukankan      html  css  js  c++  java
  • 二叉树的常见操作实现

    二叉树的常见操作实现:

    • 先序遍历、中序遍历、后序遍历层序遍历
    • 由先序序列和中序序列建立二叉树
    • 由后序序列和中序序列建立二叉树
    • 由层序序列和中序序列建立二叉树
    • 求二叉树的叶子结点数
    • 求二叉树的高度
    • 查找值为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("
    ");
    438 
    439     printf("tree_midorder: ");
    440     tree_midorder(root);
    441     printf("
    ");
    442 
    443     printf("tree_postorder: ");
    444     tree_postorder(root);
    445     printf("
    ");
    446 
    447     printf("tree_levelorder: ");
    448     tree_levelorder( root );
    449     printf("
    ");
    450 
    451 
    452     leaves = tree_leaves( root );
    453     printf("tree_leaves: %d
    ", leaves);
    454 
    455     height = tree_height( root );
    456     printf("tree_height: %d
    ", 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
    ", 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
    ", 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("
    ");
    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("
    ");
    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("
    ");
    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("
    ");
    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
    ", 'A'+x, tmp, tmp->data);
    505         }
    506         else
    507         {
    508             printf("tree_find_x( %c ) not found!
    ", '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
    ", 'A'+x, level_of_x );
    516     }
    517 
    518 
    519     printf("==============================
    ");
    520     tree_invert( root );
    521     printf("after tree_invert
    ");
    522 
    523     printf("tree_preorder: ");
    524     tree_preorder(root);
    525     printf("
    ");
    526 
    527     printf("tree_midorder: ");
    528     tree_midorder(root);
    529     printf("
    ");
    530 
    531     printf("tree_postorder: ");
    532     tree_postorder(root);
    533     printf("
    ");
    534 
    535     printf("tree_levelorder: ");
    536     tree_levelorder( root );
    537     printf("
    ");
    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

  • 相关阅读:
    常用的英文缩写
    常见的加密算法
    c# 创建socket客户端
    gvim配置到命令行可以使用
    multi-mechanize error: can not find test script: v_user.py问题
    C#类的修饰符
    淘宝-保证金缴纳的类目及对应金额(2017.3.25)
    js时间转换,能够把时间转换成yyyymmdd格式或yyyymm格式
    IP共享重新验证
    数据库自带方法
  • 原文地址:https://www.cnblogs.com/utank/p/12058322.html
Copyright © 2011-2022 走看看