UVA #10410 Tree Reconstruction [closed]
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question 开发者_运维百科I have worked on UVA 10410 Tree Reconstruction several days. But I can't get the correct answer unitl now.
I have used an algorithm similar to the one which we always use to recovery a binary tree through the preorder traversal and the inorder traversal. But it can't work.
Can anyone help me? Thanks in advance.
I think I have the hang of it. I don't pretend it's efficient though.
Let's look at the first 3 digits of the BFS output:
4 3 5
We are in one of these situations:
4 4
/ \ OR |
3 5 3
x x |
5
x
What is the DFS for those 2 cases ?
- 4 3 (3s-children) 5 (5s-children)
- 4 3 5 (5s-children)
Quick note: if 3
does not have any child, then it's impossible to tell the two apart...
If we consider that the problem is decidable, then it's a matter of knowing if 5
follows 3
in the DFS representation.
- If it does: it's a linear composition
- If it does not then you go recursive:
4
has 2 children3
and5
and you can easily identify the subtree from the DFS representation. Then extract (preserving order) the BFS representation of these subtrees from the BFS you had and recurse :)
It seems fairly far from optimal, but I am a bit more worried about the undecidability.
Is there a constraint in expression-parse trees which states that once you have a node that only has one child none of the nodes in the subtree it represents can have more than one ?
"Note that when a parent was expanded the children were traversed in ascending order." This sentence is very important!
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
struct Node
{
int value;
Node *child; //left child
Node *sibling; //right sibling
Node(int v)
{
value = v;
child = NULL;
sibling = NULL;
}
};
void BuildTree(Node *&root,vector<int> bfs,vector<int> dfs)
{
root = NULL;
if(bfs.size() == 1)
root = new Node(bfs[0]);
if(bfs.size() > 1)
{
root = new Node(bfs[0]);
vector<int> candidate; //store candidate childs
unsigned i;
for(i = 1; i < bfs.size(); i++)
{
if(bfs[i] >= bfs[1])
candidate.push_back(bfs[i]);
else
break;
}
//remove the non-candidate node
int boundOfChild = candidate.size() - 1;
for(i = candidate.size() - 1; i >= 1; i--)
{
vector<int>::iterator it1;
vector<int>::iterator it2;
it1 = find(dfs.begin(),dfs.end(),candidate[i]);
it2 = find(dfs.begin(),dfs.end(),candidate[i - 1]);
if(it1 < it2)
boundOfChild = i;
}
if(boundOfChild != candidate.size() - 1)
candidate.erase(candidate.begin() + boundOfChild,candidate.end());
//get every child's bfs and dfs
for(i = candidate.size(); i >= 1; i--)
{
vector<int>::iterator it1;
vector<int>::iterator it2;
if(i == candidate.size())
{
it1 = find(dfs.begin(),dfs.end(),candidate[i - 1]);
it2 = dfs.end();
}
else
{
it1 = find(dfs.begin(),dfs.end(),candidate[i - 1]);
it2 = find(dfs.begin(),dfs.end(),candidate[i]);
}
vector<int> tmp_dfs(it1,it2);
vector<int> tmp_bfs;
for(vector<int>::iterator it = bfs.begin(); it < bfs.end(); it++)
{
if(find(tmp_dfs.begin(),tmp_dfs.end(),*it) != tmp_dfs.end())
tmp_bfs.push_back(*it);
}
Node *tmp = root->child;
BuildTree(root->child,tmp_bfs,tmp_dfs);
root->child->sibling = tmp;
}
}
}
void PrintTree(Node *root)
{
if(root == NULL)
return;
queue<Node*> Q;
Q.push(root);
while(!Q.empty())
{
Node *tmp = Q.front();
Q.pop();
cout << tmp->value << ": ";
tmp = tmp->child;
while(tmp)
{
cout << tmp->value << ",";
Q.push(tmp);
tmp = tmp->sibling;
}
cout << endl;
}
}
//just test case
int BFS[] = {7,8,12,4,5,1,6,11,2,3,10,9,13,14};
int DFS[] = {7,8,4,5,2,3,12,1,6,10,14,11,9,13};
int main()
{
vector<int> vBFS(BFS,BFS + sizeof(BFS) / sizeof(int));
vector<int> vDFS(DFS,DFS + sizeof(DFS) / sizeof(int));
Node *root = NULL;
BuildTree(root,vBFS,vDFS);
PrintTree(root);
return 0;
}
精彩评论