链接:poj.org/problem?id=2255
题意:
分别给你一个二叉树的前序遍历序列和中序遍历序列,让你给出这个二叉树的后序遍历序列.
思路:
对于二叉树的三种遍历方式,都可以使用递归来实现,那么也一定可以使用递归来拆解,以达到从遍历序列确定二叉树具体结构的目的.对于前序遍历来说,第一个字母一定是根,并且在序列中根的左子树包含的点一定出现在根的右子树的前面.对于中序遍历序列来说,根前面出现的字母所代表的点一定出现在左子树中,根后面出现的字母所代表的点一定出现在右子树中.在根据前序与中序遍历序列还原二叉树的过程中,先由前序遍历序列确定根节点,再由根节点从中序遍历序列中确定左子树和右子树的中序遍历序列,再由左子树和右子树的中序遍历序列中的元素数目在前序遍历序列中去除根节点后截取出左子树以及右子树的前序遍历序列.然后,一颗二叉树被拆分成根节点,左子树,右子树,以及他们的前序及中序遍历序列,然后分别对左子树及右子树进行递归就可以得到答案.
代码:
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("\n"); 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] = ‘\0‘; 22 int j; 23 for(j = 0; j < i; j++) leftreeDLR[j] = fir[j + 1]; 24 leftreeDLR[j] = ‘\0‘; 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] = ‘\0‘; 32 int jj; 33 for(jj = 0; jj < ii; jj++) rightreeDLR[jj] = fir[jj + j + 1]; 34 rightreeDLR[jj] = ‘\0‘; 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("\n"); 49 } 50 return 0; 51 }
时间: 2024-11-06 18:19:56