使用2-3棵树维护列表

时间:2019-02-21 19:22:20

标签: algorithm list tree

假设我们尝试使用2-3棵树来维护列表结构,并且想要进行有效的操作来创建列表,连接,拆分并获取索引值。我尝试进行此操作的第一个尝试是将列表元素视为2-3树中的叶子,并且每个内部节点都将左边的叶子数量存储起来。这样,如果您要搜索索引,则如果您搜索的索引小于任何内部节点的值,它将向左看,否则向右看。如果找不到叶子,则索引超出范围。

但是,我不确定在连接列表时如何有效地维护此不变式。我可以将L2的树表示形式添加到L1的树中最右边的可用位置,然后尝试更新计数,然后尝试实现一些插入算法,例如2-3棵树……但至少我的直觉告诉我,我将无法提高效率(即O(log(n)))。

我应该继续尝试进行这项工作,还是我最初的决定是将计数存储在我应该考虑重新设计树的节点上?

1 个答案:

答案 0 :(得分:2)

(我要回答wrt。因为它更容易推论,所以是一棵红黑树而不是2-3棵树。此答案需要稍加调整才能使用2-3棵树)

与其让每个顶点存储左侧的元素数量,不如让每个顶点存储作为其根的子树中的元素数量。从根目录在树中向下导航时,请保持左侧元素的总和 s 。每当您移至顶点 v 的右子级时,将 v 的左子级子树中的元素数量添加到 s

在连接或拆分两个列表时,此不变式不需要更新。

要串联两个列表 A B (即,将 B 附加到 A ),只需制作一个新的顶点 v ,并分别将 A B 分别作为其左子元素和右子元素。将以 v 为根的子树中的元素数更新为 A B 中的元素数之和。

将列表分成两部分,只需删除要切断的列表根的边缘即可。

(更新)

但是,根据列表的大小,树可能会变得不平衡。经过一定数量的“不平衡”串联或拆分后,您将不得不重新平衡树。我必须承认,我不确定这是什么时间复杂性。我很确定您不能摊销固定时间,但是您也许可以摊销O(log n)时间。