zoukankan      html  css  js  c++  java
  • 由层序遍历序列和中序遍历序列确定二叉树

    如何通过层序遍历序列和中序遍历序列来确定一棵二叉树?

    • 根据层序遍历序列第一个结点确定根结点;
    • 根据根结点在中序遍历序列中分割出左右子树的中序序列;
    • 根据分割出的左右子树的中序序列从层序序列中提取出对应的左右子树的层序序列;
    • 对左子树和右子树分别递归使用相同的方式继续分解;

    要点:根据分割出的左右子树的中序序列从层序序列中提取出对应的左右子树的层序序列,分别构建出新的左右子树的层序序列和中序序列;

      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 preorder(struct node *root)
     13 {
     14     if(root)
     15     {
     16         printf("%c", root->data);       
     17         preorder(root->lt);
     18         preorder(root->rt);
     19     }
     20 }
     21 
     22 // 中序遍历
     23 void midorder(struct node *root)
     24 {
     25     if(root)
     26     {
     27         midorder(root->lt);
     28         printf("%c", root->data);          
     29         midorder(root->rt);
     30     }
     31 }
     32 
     33 // 后序遍历
     34 void postorder(struct node *root)
     35 {
     36     if(root)
     37     {
     38         postorder(root->lt);
     39         postorder(root->rt);
     40         printf("%c", root->data);
     41     }
     42 }
     43 
     44 // 层序遍历
     45 void 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[20];
    121     char right[20];
    122     int i, j, 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  *
    168  *           A
    169  *          / 
    170  *         B   C
    171  *        /  /   
    172  *       D  E G   H
    173  *         /       
    174  *        F         I
    175  **/
    176 int main( void )
    177 {
    178     struct node *root=NULL;
    179     int len;
    180     char *post = "DFEBGIHCA";
    181     char *pre = "ABDEFCGHI";
    182     char *mid = "DBFEAGCHI";
    183     char *level = "ABCDEGHFI";
    184 
    185     len = strlen(mid);
    186 
    187     //root = create_by_pre_and_mid(len, pre, mid);
    188     //root = create_by_post_and_mid(len, post, mid);
    189     root = create_by_level_and_mid( len, level, mid );
    190 
    191     printf("
    preorder:
    ");
    192     preorder(root);
    193 
    194     printf("
    midorder:
    ");
    195     midorder(root);
    196 
    197     printf("
    postorder:
    ");
    198     postorder(root);
    199 
    200     printf("
    levelorder:
    ");
    201     levelorder( root );
    202 
    203     printf("
    ");
    204 
    205     system("pause");
    206     return 0;
    207 }
  • 相关阅读:
    【STL】各容器成员对比表
    windows笔记页文件支持的内存映射文件
    windows笔记【内核对象线程同步】线程同步对象速查表
    windows笔记虚拟内存
    windows笔记使用内存映射文件在进程之间共享数据
    svn个人服务端
    解决安装Visual Studio .NET 2003 时FrontPage 2000 WEB 扩展客户端 安装失败
    vc6.0转vs2008连接错误
    Sublime Text插件推荐
    末日了,说出你的梦想、愿望还有遗憾吧。
  • 原文地址:https://www.cnblogs.com/utank/p/12052989.html
Copyright © 2011-2022 走看看