[九度][何海涛] 重建二叉树
- 题目描述:
-
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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 <iostream> 2 #include <vector> 3 using namespace std; 4 5 bool convert(int preOrder[], int preBeg, int preEnd, int inOrder[], int inBeg, int inEnd, vector<int> &postOrder) 6 { 7 if (preEnd - preBeg != inEnd - inBeg) 8 return false; 9 10 if (preBeg > preEnd) 11 return true; 12 13 int root = preOrder[preBeg]; 14 int index = -1; 15 for(int i = inBeg; i <= inEnd; i++) 16 if (inOrder[i] == root) 17 { 18 index = i; 19 break; 20 } 21 22 if (index == -1) 23 return false; 24 25 int len = index - inBeg; 26 bool left = convert(preOrder, preBeg + 1, preBeg + len, inOrder, inBeg, index - 1, postOrder); 27 bool right = convert(preOrder, preBeg + len + 1, preEnd, inOrder, index + 1, inEnd, postOrder); 28 postOrder.push_back(root); 29 30 return left && right; 31 } 32 33 int main() 34 { 35 int n; 36 int preOrder[1000]; 37 int inOrder[1000]; 38 while(cin >> n) 39 { 40 for(int i = 0; i < n; i++) 41 cin >> preOrder[i]; 42 for(int i = 0; i < n; i++) 43 cin >> inOrder[i]; 44 45 vector<int> postOrder; 46 47 bool res = convert(preOrder, 0, n - 1, inOrder, 0, n - 1, postOrder); 48 49 if (res) 50 { 51 for(int i = 0; i < postOrder.size(); i++) 52 cout << postOrder[i] << ' '; 53 cout << endl; 54 } 55 else 56 cout << "No" << endl; 57 } 58 }