您的位置:首页 > 其它

[九度][何海涛] 重建二叉树

2012-11-21 11:30 399 查看
题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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

中序:左根右,前序:根左右。先靠前序把根确定,然后在中序中找根,没找到则不可能。找到就能确定中序中的左半部分右半部分,同时可以推出前序中的左和右,这样就能递归解决子问题。


#include <iostream>
#include <vector>
using namespace std;

bool convert(int preOrder[], int preBeg, int preEnd, int inOrder[], int inBeg, int inEnd, vector<int> &postOrder)
{
if (preEnd - preBeg != inEnd - inBeg)
return false;

if (preBeg > preEnd)
return true;

int root = preOrder[preBeg];
int index = -1;
for(int i = inBeg; i <= inEnd; i++)
if (inOrder[i] == root)
{
index = i;
break;
}

if (index == -1)
return false;

int len = index - inBeg;
bool left = convert(preOrder, preBeg + 1, preBeg + len, inOrder, inBeg, index - 1, postOrder);
bool right = convert(preOrder, preBeg + len + 1, preEnd, inOrder, index + 1, inEnd, postOrder);
postOrder.push_back(root);

return left && right;
}

int main()
{
int n;
int preOrder[1000];
int inOrder[1000];
while(cin >> n)
{
for(int i = 0; i < n; i++)
cin >> preOrder[i];
for(int i = 0; i < n; i++)
cin >> inOrder[i];

vector<int> postOrder;

bool res = convert(preOrder, 0, n - 1, inOrder, 0, n - 1, postOrder);

if (res)
{
for(int i = 0; i < postOrder.size(); i++)
cout << postOrder[i] << ' ';
cout << endl;
}
else
cout << "No" << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: