Data structures 给定一个二元搜索树,打印构成相同BST的所有输入组合

Data structures 给定一个二元搜索树,打印构成相同BST的所有输入组合,data-structures,Data Structures,比如说, 输入二叉树是 2 3 1 我们需要为相同的二叉树结构打印所有可能的组合(不需要树平衡) 231213 注意:123不是有效的输出,因为它将更改树结构 如果图案较长,则会变得复杂 另一个例子 5 3 7 2 4 6 8 在这种情况下 5 3 7 2 4 6 8 5324768 57324468 我想知道是否有任何算法可以找到给出相同二叉树的模式 这个问题比表面上看起来更难 考虑第一个示例中的树:

比如说,

输入二叉树是

     2 
3         1 
我们需要为相同的二叉树结构打印所有可能的组合(不需要树平衡)

231213

注意:123不是有效的输出,因为它将更改树结构

如果图案较长,则会变得复杂

另一个例子

         5 
      3     7
   2    4  6   8
在这种情况下

5 3 7 2 4 6 8

5324768

57324468


我想知道是否有任何算法可以找到给出相同二叉树的模式

这个问题比表面上看起来更难

考虑第一个示例中的树:

  2
1   3
正如您所说,有两种可能的输入顺序:
2,1,3
,和
2,3,1
。规则是:根,然后按任意顺序排列子级

但那太容易了。要了解问题的全部复杂性,您必须将其扩展到另一个级别。因此,您的第二个示例:

      5 
   3     7
2    4  6   8
通常有两种方法来构造此树:广度优先或深度优先。要做到广度优先,您需要反复应用“根优先,然后按任意顺序排列子对象”规则。因此:

5,3,7,2,4,6,8
5,3,7,2,4,8,6
5,3,7,2,6,4,8
...
5,7,3,8,6,4,2
每个级别都有(2^k)!置换,其中k是级别。所以在根上有1个置换,在第二层有两个置换(k==1),在下一层有24个置换,等等

但这种广度优先的做法不会产生所有可能的有效输入。例如,
5,3,2,4,7,6,8
是完全有效的。要获得所有有效输入,还必须包括深度优先构造。这里的事情变得很有趣

您可以生成树的预顺序遍历:
5,3,2,4,7,6,8
,或反向预顺序遍历:
5,7,6,8,3,2,4
。这里的规则是root,然后以任何顺序首先遍历子深度

但这并不包括
5,3,2,7,8,4,6
这种奇怪的情况,它只是在某种程度上跳过,但确保节点的父节点是在其任何子节点之前提供的

我没有一个完整的解决方案,但我可以给你一个算法的开始。考虑随机生成有效输入序列的情况。您可以通过循环来实现这一点:

nodes_array = create an array of nodes that can be selected
output_array = array of selected nodes

add root to nodes_array
while nodes_array is not empty
    temp = randomly select node from nodes_array, and remove it
    if temp.left != null
        add temp.left to nodes_array
    if temp.right != null
        add temp.right to nodes_array
    append temp to output_array
end while
这将始终生成有效的输入,因为子节点永远不会添加到输出数组中,除非已选择其父节点


因此,生成所有有效组合的问题变成了更改随机选择步骤的问题,以便在每个级别生成
节点\u数组的所有可能排列。生成置换是一个已解决的问题。不过,递归地应用它需要一些思考。

这里有一个在Python中使用回溯的简单算法。它假设一个具有
insert
操作的二叉搜索树的实现。每个节点在
node.value
处都有一个值,并且可能在
node.left
node.right
处有子节点

def get_children(node):
    children = []
    if node.left is not None:
        children.append(node.left)
    if node.right is not None:
        children.append(node.right)
    return children

def print_permutations(possibilities, string):
    if len(possibilities) == 0:
        print(string)
        return

    for i in range(len(possibilities)):
        node = possibilities[i]
        del possibilities[i]
        new_possibilities = get_children(node) + possibilities
        print_permutations(new_possibilities, string + " " + str(node.value))
        possibilities.insert(i, node)
其思想是,每次从下一个编号的可能候选列表中选择一个节点时,都会将该节点的子节点添加到可能候选列表中。一旦没有更多的候选人,您就已经找到了一个可能的订单

你可以这样称呼它:

b = BinarySearchTree()
b.insert(5)
b.insert(3)
b.insert(7)
b.insert(2)
b.insert(4)
b.insert(6)
b.insert(8)

print_permutations(get_children(b.root), str(b.root.value))
它将输出:

5 3 2 4 7 6 8
5 3 2 4 7 8 6
5 3 2 7 6 8 4
5 3 2 7 6 4 8
5 3 2 7 8 6 4
...

我采用了一种非常简单的方法:使用递归按以下顺序打印节点:根>左子>右子

请注意:也可以打印其他有效序列:根>右子>左子。 为了简单起见,我在这里给出了第一类有效序列的代码

这是我的密码:

class Node: 
  
    # Constructor to create a new node 
    def __init__(self, data): 
        self.data = data 
        self.left = None
        self.right = None

root = Node(20) 
root.left = Node(8) 
root.right = Node(22) 
root.left.left = Node(4) 
root.left.right = Node(12) 
root.left.right.left = Node(10) 
root.left.right.right = Node(14)
问题的实质是:

def printNodes(root):
    
    if root == None:
        return False
    else:
        print(root.data)
        printNodes(root.left)
        printNodes(root.right)
输出:

printNodes(root)

20
8
4
12
10
14
22

你是说二叉搜索树,对吗?(常规二叉树并不意味着节点的任何排序)您需要详细说明如何允许您从给定模式生成此树。例如,
123445
是否是示例中树的有效模式?如果没有,为什么不呢?我现在已经更新了问题。。。如果不清楚,请告诉我您提到的
123
无效,因为它将更改树结构,但是,由于您没有给出如何从模式生成树的规则,因此没有任何东西阻止您绘制的树成为
123
的有效树。我假设您假定模式是树的层次顺序遍历(请参阅,但您绝对需要明确说明这一点。我在这里回答了这个问题: