- 题目描述:
-
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。
- 输入:
-
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为一个整数n(1<=n<=1000):代表二叉树的节点个数。
输入的第二行包括n个整数(其中每个元素a的范围为(1<=a<=1000)):代表二叉树的前序遍历序列。
输入的第三行包括n个整数(其中每个元素a的范围为(1<=a<=1000)):代表二叉树的中序遍历序列。
- 输出:
-
对应每个测试案例,输出一行:
如果题目中所给的前序和中序遍历序列能构成一棵二叉树,则输出n个整数,代表二叉树的后序遍历序列,每个元素后面都有空格。
如果题目中所给的前序和中序遍历序列不能构成一棵二叉树,则输出”No”。
- 样例输入:
-
8 1 2 4 7 3 5 6 8 4 7 2 1 5 3 8 6 8 1 2 4 7 3 5 6 8 4 1 2 7 5 3 8 6
- 样例输出:
-
7 4 2 5 8 6 3 1 No
这道题和清华的机试题一样,但多了判断,我的判断开始少了一个条件,导致一直错误1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <string> 5 6 #define MAX 1002 7 8 int front[MAX]; 9 int middle[MAX]; 10 int back[MAX]; 11 12 13 bool backOut(int start, int end, int fb, int num) { 14 int wei; 15 bool isOk = false; 16 if(start == end) { 17 if(front[fb] == middle[start]) { 18 back[num] = front[fb]; 19 return true; 20 } 21 else { 22 return false; 23 } 24 } 25 for(int i = start; i <= end; i++) { 26 if(middle[i] == front[fb]) { 27 wei = i; 28 isOk = true; 29 break; 30 } 31 } 32 if(!isOk) { 33 return false; 34 } 35 back[num] = front[fb]; 36 if(start != wei) { 37 isOk = isOk && backOut(start, wei-1, fb+1, num-end+wei-1); 38 } 39 if(end != wei) { 40 isOk = isOk && backOut(wei+1, end, fb+wei-start+1, num-1); 41 } 42 return isOk; 43 } 44 45 int main(int argc, char const *argv[]) 46 { 47 int n; 48 //freopen("input.txt","r",stdin); 49 while(scanf("%d",&n) != EOF) { 50 51 for(int i = 0; i < n; i++) { 52 scanf("%d",&front[i]); 53 } 54 for(int i = 0; i < n; i++) { 55 scanf("%d",&middle[i]); 56 } 57 if(backOut(0, n-1, 0, n-1)) { 58 for(int i = 0; i < n; i++) { 59 printf("%d ", back[i]); 60 } 61 printf(" "); 62 } 63 else { 64 puts("No"); 65 } 66 67 } 68 return 0; 69 }