这个问题比表面看起来的要难。
考虑你第一个示例中的树:
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”。规则是根,然后以任何顺序深度优先遍历子项。
但是,这并没有涵盖“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
这应该总是生成一个有效的输入,因为除非其父节点已被选择,否则永远不会将子节点添加到输出数组中。
因此,生成所有有效组合的问题就变成了更改随机选择步骤,使得在每个级别它生成 nodes_array
的所有可能排列。生成排列是一个解决的问题。然而,递归应用这一点需要一些思考。
1 2 3 4 5
是你例子中树的有效模式吗?如果不是,为什么不是? - Bernhard Barker123
不合法是因为它会改变树的结构,但是,由于你没有给出从模式生成树的规则,所以你画的树可能是123
的有效树。我猜测你认为该模式是树的层序遍历(参见 维基百科),但你绝对需要明确说明这一点。 - Bernhard Barker