给定有序遍历的所有可能的二叉树的预序遍历

时间:2018-07-11 08:52:20

标签: c++ binary-tree inorder preorder

我正在查看有关二叉树的问题,并且遇到了以下问题: 给定二叉树的有序遍历,请打印满足给定有序遍历的所有可能的二叉树的有序遍历。

例如,如果有序遍历为:{4,5,7} 可能的树是:

4         4           5         7       7
 \          \       /   \      /       /
  5          7     4     7    4       5
   \        /                  \     /
    7      5                    5   4 

因此,预遍历为:

4 5 7  
4 7 5 
5 4 7 
7 4 5 
7 5 4 

我想到的解决方案: 遍历给定的顺序列表。每次迭代时,从列表中选择一个元素,并将其设为树的根。当前一个之前的所有元素将成为左子树的一部分,而其后的所有元素将形成右子树。然后,我们可以递归地对左和右子树执行相同的操作。

例如,在上面的示例中,我首先选择4作为树的根。现在,由于在4之前没有元素,所以我没有左子树。我看看其余的元素。它们将形成正确的子树。我选择5作为此子树的根。为此,我只有一个选择:从7构建5的右子树。这给出了示例的第一棵树。

现在,我保留4作为根,而不是选择5,而是选择7作为4的右子树的根。这将导致我转到上面示例的第二棵树。

那很好。问题出在代码上。我花了很长时间将上述解决方案转换为代码。但是我还没有完全成功。

这是我在C ++中尝试过的方法:

void solve(vector<int> inOrder, int beg, int end, string &s, bool &flag)
{
    for(int i = beg; i <= end; ++i)
    {
        s += to_string(inOrder[i]);
        flag = false;
        solve(inOrder, beg, i - 1, s, flag);
        solve(inOrder, i + 1, end, s, flag);
        if(s.size() == inOrder.size()) {flag = true; cout << s << endl;}
        if(s.size() && flag) {s.pop_back();}
    }
}

我使用一个字符串存储元素在预遍历中的当前排列。当排列满足有序遍历时,会将元素添加到字符串。

自然地,随后必须从字符串中删除元素,以便为其他排列让路。但是,我无法找出何时删除元素。在上面的代码中,我在第一次遇到元素时追加了元素,并且当字符串的大小等于顺序列表的大小时,我开始删除元素。

因此,假设我从4开始。我在字符串后附加4。我先对5进行同样的操作,然后对7进行同样的操作。现在,字符串大小等于元素总数。所以我删除了最后一个。我的字符串现在为45。由于当前字符串不再有可能的组合,因此我删除了5。剩下的是4。现在,我可以附加7,然后附加5,导致475。在这种情况下,这种方法工作正常,但我无法使其适用于其他组合。当我以5而不是4为根时,它会失败。

所以我的问题是,我应该如何继续解决上述问题?我什至以正确的方式做吗?还是我应该放弃这种方法而想到其他东西?如果是,我应该朝哪个方向前进?

我不是在寻找确切的解决方案,只是关于我所缺少的或我可以做得更好的提示。

0 个答案:

没有答案