zoukankan      html  css  js  c++  java
  • POJ 2255 Tree Recovery && Ulm Local 1997 Tree Recovery (二叉树的前中后序遍历)

    链接:poj.org/problem?id=2255

    本文链接:http://www.cnblogs.com/Ash-ly/p/5463375.html

    题意:

      分别给你一个二叉树的前序遍历序列和中序遍历序列,让你给出这个二叉树的后序遍历序列.

    思路:

      对于二叉树的三种遍历方式,都可以使用递归来实现,那么也一定可以使用递归来拆解,以达到从遍历序列确定二叉树具体结构的目的.对于前序遍历来说,第一个字母一定是根,并且在序列中根的左子树包含的点一定出现在根的右子树的前面.对于中序遍历序列来说,根前面出现的字母所代表的点一定出现在左子树中,根后面出现的字母所代表的点一定出现在右子树中.在根据前序与中序遍历序列还原二叉树的过程中,先由前序遍历序列确定根节点,再由根节点从中序遍历序列中确定左子树和右子树的中序遍历序列,再由左子树和右子树的中序遍历序列中的元素数目在前序遍历序列中去除根节点后截取出左子树以及右子树的前序遍历序列.然后,一颗二叉树被拆分成根节点,左子树,右子树,以及他们的前序及中序遍历序列,然后分别对左子树及右子树进行递归就可以得到答案.

    代码:

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 typedef long long LL;
     7 const int maxN = 31;
     8 
     9 char preord[maxN], inord[maxN];
    10 void recover(int preleft, int preright, int inleft, int inright)
    11 {
    12     int root, leftsize, rightsize;
    13 
    14       //find root in inorder traversal
    15     for (root = inleft; root <= inright; root++)
    16         if (preord[preleft] == inord[root]) break;
    17 
    18       //compute sizes of subtrees
    19     leftsize = root - inleft;
    20     rightsize = inright - root;
    21 
    22        //recover subtrees 
    23     if(leftsize > 0)  recover(preleft + 1, preleft + leftsize, inleft, root - 1);
    24     if(rightsize > 0) recover(preleft + leftsize + 1, preright, root + 1, inright);
    25     
    26       //root 
    27     printf("%c", inord[root]);
    28 }
    29 
    30 void solve()
    31 {
    32     int len = strlen(preord);
    33     recover(0, len - 1, 0, len - 1);
    34     printf("
    ");
    35 }
    36 
    37 int main()
    38 {
    39     freopen("input.txt", "r", stdin);
    40     while (~scanf("%s%s", preord, inord))solve();
    41     return 0;
    42 }

    代码二:

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <algorithm>
     7 #include <queue>
     8 #include <stack>
     9 #include <vector>
    10   
    11 using namespace std;  
    12 const int MAXN = 1000;
    13 
    14 void getLRD(char fir[MAXN + 7], char mid[MAXN + 7]){
    15     int lenf = strlen(fir), lenm = strlen(mid);
    16     char root = fir[0];
    17     //find leftsuntree DLR ans LDR
    18     char leftreeDLR[MAXN + 7] = {0}, leftreeLDR[MAXN + 7] = {0};
    19     int i;
    20     for(i = 0; mid[i] != root && i < lenm; i++) leftreeLDR[i] = mid[i];
    21     leftreeLDR[i] = '';
    22     int j;
    23     for(j = 0; j < i; j++) leftreeDLR[j] = fir[j + 1];
    24     leftreeDLR[j] = '';
    25     if(i < 2 && j < 2)printf("%s", leftreeDLR);
    26     else getLRD(leftreeDLR, leftreeLDR);
    27   //find rightsuntree DLR ans LDR
    28     char rightreeDLR[MAXN + 7] = {0}, rightreeLDR[MAXN + 7] = {0};
    29     int ii;
    30     for(ii = 0; ii < lenm - 1 - i; ii++) rightreeLDR[ii] = mid[ii + i + 1];
    31     rightreeLDR[ii] = '';
    32     int jj;
    33     for(jj = 0; jj < ii; jj++) rightreeDLR[jj] = fir[jj + j + 1];
    34     rightreeDLR[jj] = '';
    35     if(ii < 2 && jj < 2)printf("%s", rightreeDLR);
    36     else getLRD(rightreeDLR, rightreeLDR);
    37   //root
    38     printf("%c", root);  
    39 }
    40 
    41 int main()
    42 {
    43     //freopen("input.txt", "r", stdin);  
    44     char DLR[MAXN+7], LDR[MAXN + 7];
    45     while(~scanf("%s%s", DLR, LDR)){
    46         char LRD[MAXN] = {0};
    47         getLRD(DLR, LDR);
    48         printf("
    ");
    49     }
    50     return 0;  
    51 }  
  • 相关阅读:
    Android 常用开发类库
    Java 8 时间日期库的20个使用演示样例
    数据格式转换 (三)Office文档转HTML
    2011年读过的书及2012年即将要读的书
    nodeJs学习路线
    Android入门篇(一)Androidproject的搭建,导入与导出,图标的改动
    MySQL 使用自增ID主键和UUID 作为主键的优劣比較具体过程(从百万到千万表记录測试)
    实战Jquery(四)--标签页效果
    Xcode加入应用图标以及启动界面
    poj 2240 Bellman-Flod 求环
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5463375.html
Copyright © 2011-2022 走看看