从inorder遍历打印所有二叉树

时间:2012-01-03 23:36:05

标签: c++ binary-tree

在接受采访时遇到了这个问题。 给定遍历二叉树的顺序。从中打印所有可能的二叉树。

初步想法:

如果说我们阵列中只有2个元素。说2,1。 然后是两棵可能的树

              2 
               \
                1     
    1
   /
   2  

如果3个元素说,2,1,4。然后我们有5棵树。

 2               1            4           2            4
  \             / \          /             \          /
   1           2   4        1               4        2
    \                      /               /          \
     4                    2               1            1

所以,基本上如果我们有n个元素,那么我们有n-1个分支(childs,/或)。 我们可以按任何顺序安排这些n-1个分支。 对于n = 3,n-1 = 2.因此,我们有2个分支。 我们可以通过以下方式安排2个分支:

  /     \         \           /         /\
 /       \        /           \

初步尝试:

struct  node *findTree(int *A,int l,int h)
{
    node *root = NULL;
    if(h < l)
            return NULL;
    for(int i=l;i<h;i++)
    {
            root = newNode(A[i]);
            root->left = findTree(A,l,i-1);
            root->right = findTree(A,i+1,h);
            printTree(root);
            cout<<endl;
    }

}

2 个答案:

答案 0 :(得分:4)

这个问题很好地分解为子问题。给定一个inorder遍历,在选择一个根之后,我们知道之前的所有内容都是左子树,而后面是正确的子树(可能是空的)。

因此,为了枚举所有可能的树,我们只是尝试所有可能的根值,并递归求解左和下;正确的子树(虽然这些树的数量增长很快!)

antonakos提供了显示如何执行此操作的代码,尽管该解决方案可能会使用比预期更多的内存。这可以通过在递归中添加更多状态来解决,因此它不必保存左侧和右侧的答案列表。对,并在最后结合它们;而是嵌套这些进程,并在找到它们时打印每个树。

答案 1 :(得分:1)

我会编写一个用于构建树的函数,另一个用于打印它们。

树木的建造是这样的:

#include <vector>
#include <iostream>
#include <boost/foreach.hpp>

struct Tree {
    int value;
    Tree* left;
    Tree* right;

    Tree(int value, Tree* left, Tree* right) :
        value(value), left(left), right(right) {}
};

typedef std::vector<Tree*> Seq;

Seq all_trees(const std::vector<int>& xs, int from, int to)
{
    Seq result;
    if (from >= to) result.push_back(0);
    else {
        for (int i = from; i < to; i++) {
            const Seq left = all_trees(xs, from, i);
            const Seq right = all_trees(xs, i + 1, to);
            BOOST_FOREACH(Tree* tl, left) {
                BOOST_FOREACH(Tree* tr, right) {
                    result.push_back(new Tree(xs[i], tl,  tr));
                }
            }
        }
    }
    return result;
}

Seq all_trees(const std::vector<int>& xs)
{
    return all_trees(xs, 0, (int)xs.size());
}

观察到对于根值,有多个树可以从根值的左侧和右侧的值构造。包括这些左右树的所有组合。

编写漂亮的打印机是一个练习(一个无聊的),但我们可以测试该函数确实构建了预期的树数:

int main()
{
    const std::vector<int> xs(3, 0); // 3 values gives 5 trees.
    const Seq result = all_trees(xs);
    std::cout << "Number of trees: " << result.size() << "\n";
}