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
的有效树。我假设您假定模式是树的层次顺序遍历(请参阅,但您绝对需要明确说明这一点。我在这里回答了这个问题: