假设我有一个像这样的二叉树 -
5
/ \
/ \
/ \
/ \
2 8
/ \ / \
/ \ / \
1 3 6 9
\ \ \
4 11 10
现在我有一个随机生成器,它将生成1到树大小的数字(在本例中为10)。基于随机生成器生成的随机值,我必须从树中返回节点(假设,生成器给定7,所以我返回第7个节点(值11),进行inorder遍历)。明天我再向树中添加4个节点。如何保持一致性?与此同时,返回树中的相同节点作为随机值。 inorder遍历将创建一个不同的数组,索引的值将会改变。
答案 0 :(得分:5)
除非您的目标是通过向其添加节点来构建二叉树,并且冻结某个点上的索引和节点之间的映射,否则您的问题确实没有意义,所以未来添加到树中(在冻结点之后)不会更改该映射。
目前还不清楚你想要完成什么,但我可以看到几种可能性。如果您的意图是可以在树中的任何位置添加新节点,那么它们实际上不能有任何合理映射到它们的索引。在这种情况下,我只是在冰点处创建一个地图(例如HashMap
),以将索引映射到节点。使用有序遍历遍历树,构建映射,并将其与树结构一起保存。使用映射确定索引的节点,而不是遍历树。
如果,不是在树中的任意位置添加节点,你想在一个地方添加节点使原来的节点仍然将具有相同的指数,那么所有你需要做的是往下走的树'的权利孩子,直到你没有正确的孩子的节点。在您发布的示例中,这将是节点10
:
5
/ \
/ \
/ \
/ \
2 8
/ \ / \
/ \ / \
1 3 6 9
\ \ \
4 11 10**
在要冻结的位置标记该节点。然后,当增加一个新的节点,则新节点必须添加为任一标记的节点的右子 - 或者,如果所述标记的节点具有右子 - [R (因为你'已经已经在冻结后添加了一个),它将成为 R 的后代。以这种方式添加的新节点将始终在有序遍历中成功地存在于冰点处的节点。因此,先前添加的节点的索引不会受到影响。
如果这些都不是你想要的,你需要提供更多关于你需要的说明。
答案 1 :(得分:1)
一种选择是在有序遍历中添加任何新节点作为最后一个节点的右子节点。这将导致一棵非常深的和不平衡的树;你没有要求一棵平衡的树,所以这可能就是好的。