Algorithm UVA#10410树重建

Algorithm UVA#10410树重建,algorithm,tree,Algorithm,Tree,我已经工作了好几天了。但是我现在不能得到正确的答案 我使用了一种类似于我们通常使用的通过前序遍历和顺序遍历来恢复二叉树的算法。但它不能工作 有人能帮我吗?提前谢谢。我想我已经掌握了窍门。不过,我并不假装它很有效 让我们看看BFS输出的前3位数字: 4 3 5 我们正处于以下情况之一: 4 4 / \ OR | 3 5 3 x x | 5 x 这两个案例的DFS是多少 4 3(3个孩

我已经工作了好几天了。但是我现在不能得到正确的答案

我使用了一种类似于我们通常使用的通过前序遍历和顺序遍历来恢复二叉树的算法。但它不能工作


有人能帮我吗?提前谢谢。

我想我已经掌握了窍门。不过,我并不假装它很有效

让我们看看BFS输出的前3位数字:

4 3 5
我们正处于以下情况之一:

  4         4
/  \   OR   |
3  5        3
x  x        |
            5
            x
这两个案例的DFS是多少

  • 4 3(3个孩子)5(5个孩子)
  • 4 3 5(5个儿童)
快速提示:如果
3
没有孩子,那么就无法区分这两个孩子

如果我们认为问题是可判定的,那么在DFS表示中是否知道<代码> 5 遵循<代码> 3 <代码>。

  • 如果是:它是一个线性组合
  • 如果没有,则返回递归:
    4
    有两个子项
    3
    5
    ,您可以很容易地从DFS表示中识别子树。然后从您拥有的BFS中提取(保留顺序)这些子树的BFS表示并递归:)
这似乎远远不是最优的,但我更担心的是不确定性

表达式解析树中是否存在一个约束,该约束规定,一旦节点只有一个子节点,它所表示的子树中的任何节点都不能有多个子节点

“请注意,当展开父对象时,子对象在 升序。” 这句话很重要

#包括
#包括
#包括
#包括
使用名称空间std;
结构体类型
{
int值;
Node*child;//左子节点
节点*同级;//右同级
节点(INTV)
{
值=v;
child=NULL;
同级=空;
}
};
void构建树(节点*&根、向量bfs、向量dfs)
{
root=NULL;
如果(bfs.size()==1)
根=新节点(bfs[0]);
如果(bfs.size()>1)
{
根=新节点(bfs[0]);
向量候选;//存储候选子对象
未签名的i;
对于(i=1;i=bfs[1])
候选者。推回(bfs[i]);
其他的
打破
}
//删除非候选节点
int boundOfChild=candidate.size()-1;
对于(i=candidate.size()-1;i>=1;i--)
{
向量::迭代器it1;
向量::迭代器it2;
it1=find(dfs.begin()、dfs.end()、候选者[i]);
it2=find(dfs.begin(),dfs.end(),候选者[i-1]);
如果(it1=1;i--)
{
向量::迭代器it1;
向量::迭代器it2;
如果(i==candidate.size())
{
it1=find(dfs.begin(),dfs.end(),候选者[i-1]);
it2=dfs.end();
}
其他的
{
it1=find(dfs.begin(),dfs.end(),候选者[i-1]);
it2=find(dfs.begin()、dfs.end()、候选者[i]);
}
向量tmp_dfs(it1,it2);
向量tmp_-bfs;
对于(vector::iterator it=bfs.begin();it子节点;
构建树(根->子级、tmp_bfs、tmp_dfs);
根->子->同级=tmp;
}
}
}
无效打印树(节点*根)
{
if(root==NULL)
返回;
队列Q;
推(根);
而(!Q.empty())
{
节点*tmp=Q.front();
Q.pop();
不能重视儿童;
while(tmp)
{
不能重视兄弟姐妹;
}

cout看起来很有趣!这将是我的新玩具问题:我有一个想法。请注意这句话:“注意,当父对象被展开时,子对象被按升序遍历。”。我会尽快粘贴我的代码。我认为可判定性无关紧要。解决方案应该是找到任何适合的树,可以有多个答案。此外,问题陈述中提到的解析树只是故事的一部分,给定的遍历不一定是解析树的遍历:)。它可以是任何树…我知道aven没有提交它,因为函数PrintTree应该重写以满足要求-“按升序”.但我认为我的算法应该是正确的。这似乎很简单。将值输出到一个临时向量,用
std::sort
对该向量排序,然后打印该向量。这不是最有效的,但您可以担心以后可能出现的TLE。
#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;
}