生成从1到n的所有二进制搜索树

时间:2013-12-06 23:30:58

标签: algorithm

我遇到了以下问题:

给定正整数n,生成所有具有节点1,2,...,n的二叉搜索树。

例如,给定3,获得:

enter image description here

我正在做以下事情:

Generate all the permutations of the sequence (1, 2, ..., n).
For each permutation p:
    Create a tree t.
    For each number n in p:
        Insert n into t.
    If t has not yet been generated, keep it. <-- Expensive Operation

然而,这种方法很慢,因为生成了重复的树(对于n = 3,(2,1,3)和(2,3,1)生成相同的树),我需要确保它们不被保留。有人会指出我更快的方法吗?

2 个答案:

答案 0 :(得分:4)

这是伪代码,没有重复(但你仍然需要很多空间,因为没有树生成很高)。

TreeList void genAllBST(int high,int low) {

  if(high>=low) {
      currList = []
      for(int i=low;i<=high;i++) {
          curr = new Node(i);
          leftList = genAllBST(i-1,low);
          rightList = genAllBST(high,i+1);
          TreeList c = connect(curr,leftList,rightList);  
          currList.add(c);
      }

     return(currList);

  }

   return(null);
}

genAllBST(n,1);

答案 1 :(得分:0)

让我们以自下而上的方式理解它。自下而上的方法说明了什么?问题1:我们知道N = 0的答案吗?问题2:我们知道N = 1的答案吗?问题3:我们知道N = 2的答案吗?问题4:是否存在模式关系?问题5:是否存在N = i的解决方案,可以解决i = k的N = k的问题?如果以积极的方式回答了这些问题,那么我们可以说这是一个编程问题,可以通过递归或动态编程来解决。

让T(n)为n个元素的bst数。

给出n个不同的有序元素,编号从1到n,我们选择i作为根。

对于T(i-1)组合,这在左子树中留下(1..i-1),对于T(n-i)组合,在右子树中留下(i + 1..n)。

因此:

T(n) = sum_i=1^n(T(i-1) * T(n-i))

,当然T(1)= 1

您还可以检查:https://www.geeksforgeeks.org/construct-all-possible-bsts-for-keys-1-to-n/