BST输入的可能排列

时间:2012-11-20 16:52:49

标签: algorithm language-agnostic permutation binary-search-tree

我收到了一个字符串,即“CPHBDZ”。通过(按此顺序)将字母插入BST,我将:

  C
 / \
B   P
   / \
  H   Z
 /
D

如果我们将字符串的顺序更改为“CBPHDZ”,我们将得到相同的树。 我必须找到并列出提供相同BST的输入字符串的所有排列。我想出了如何计算这些排列的数量,但我无法弄清楚任何实际找到它们的算法。

2 个答案:

答案 0 :(得分:6)

假设您没有进行任何轮换(等)来平衡树,您可以从树的结构中获得答案:新节点总是作为现有节点的后代添加,因此树中的任何节点都更高必须在它自己的后代之前,但可以随意重新安排其“同伴”(任何既不是它的父母也不是后代)。

例如,由于您有C作为树的根,C必须是从流中读取的第一个项目。由于其后代是BP,因此输入中的下一项必须是这两项中的一项。 B没有任何后代,但P有两个:HZ,因此必须在P之后阅读,但可以在任何与B有关的订单。同样,Z可以是HD的任何顺序,但H必须位于D之前。

编辑:至于生成所有这些排列,一种简单(作弊)的方式是使用Prolog。基本上,您将依赖关系编码为“事实”,并且它将生成适合这些事实的所有排列。事实上(没有双关语意),这几乎就是对Prolog所做的事情的描述。

自己动手,你可能想要递归地完成大部分工作。有效排序是根,后跟其后代的有效订单的任何交错。

就如何进行交织而言,您将(例如)生成左子树的一个有效顺序和右子树的一个有效顺序。将它们放在一个数组中,其中包含开头左侧子树中的所有项目,以及最后右侧子树中的所有项目。为了演示,我们假设树还包含A(作为您显示的B的后代)。在数组中,来自子树的数据如下所示:

B A P H Z D

然后我们从左子树的最后一个项目开始,并在每个数组中向右“走”,每次都生成一个新的排列:

B P A H Z D
P B A H Z D
B P H A Z D
P B H A Z D
P H B A Z D
[ ... ]    

对于左子树的每个有效顺序,您需要使用右子树的每个有效顺序执行所有这些交错(并将其返回到父级,这将执行相同的操作)。

答案 1 :(得分:3)

在Python中,

tree = {
    'C' : ['B', 'P'],
    'P' : ['H','Z'],
    'H' : ['D']}

def f(tree,  ready):
    if not ready:
        return [[]]
    else:
        rv = []
        for r in ready:
            for rest in f(tree,
                          [n for n in ready if r != n] + tree.get(r, [])):
               rv.append([r] + rest)
        return rv

for o in f(tree, 'C'):
    print ''.join(o)