是否存在用于快速列表操作和订单查询的数据结构?


9

我们有一个集合中的元素列表。中的每个元素都显示在L中的单个列表中。我正在寻找可以执行以下更新的数据结构:LN={1,2,3,...,n}NL

  1. concat(x,y):将包含y的列表连接y到包含x的列表的末尾x

  2. split(x):含有分割列表x后直接x

它还需要执行以下查询:

  1. follows(x,y):返回true,如果xy是在同一列表和y后自带x(但不一定是相邻的x

  2. first(x):返回包含x的列表的第一个元素x

  3. next(x):返回下一个元素后x在含列表x

我已经想出了一个数据结构,该结构在O(lg ^ 2(n))中执行这些更新,O(lg2(n))并在O(lg(n))时间内进行查询。我最感兴趣的是是否已经有一个数据结构可以做到这一点(希望更快吗?)。

动机:可以用其中的两个列表集来表示有根的定向森林,它们可以快速计算此类森林的可达性。我想看看它们还有什么用,如果所有这些都已知。

Answers:


11

将整数保留在跳过列表中。正常的跳过列表按键排序,但是我们仅将它们用作序列的表示形式。此外,维护大小为的指针数组。数组的每个元素都应指向跳过列表中的一个节点。我相信这支持在和所有其他操作。nnextO(1)O(lgn)

特别:

  • concat或两个跳过列表需要时间,因此最多会使指针无效。splitO(lgn)O(lgn)
  • next,在叶子级别上紧跟前向指针,花费时间。O(1)
  • first需要时间:跟随指针直到被卡住,然后跟随左指针。当您再也无法跟随左指针时,您将位于跳过列表的开头。跟随指针指向叶子,然后跟随一个向前指针。这是列表中的第一个元素。O(lgn)
  • follows比较棘手。对进行处理,但记录一个卡住的值的列表(即,您不再可以跟踪指针的位置)。我们称此列表为您记录的“跟踪”。对进行相同的操作,但是在卡住时要遵循正确的指针,而不是向左。如果在之前,则它们的轨迹将相交。迹线的大小为。如果跟踪中的每个元素都用固定级别进行注释,则可以检查时间的交集。firstyxxyO(lgn)O(lgn)

next是最坏的情况,所有其他情况都是而且概率很高。通过使用确定性跳过列表,可以使它们变得最坏。O(1)O(lgn)

我认为可以通过使用叶级链接的(2,5)树并增强刺来使变为。有关引导技巧,请参阅Kaplan和Tarjan 撰写的 “可连接排序列表的纯函数表示形式 ”。concatO(lglgn)


凉。我当时在考虑跳过列表,但是在没有关联的键值的情况下无法完全遵循。
沙绍·尼科洛夫

这很棒; 我知道如何使所有更新都是确定性,这很好。我将不得不继续阅读以了解O(lg lg(n))。感谢您的帖子@jbapple。O(lg(n))
2011年

1

不常见的祖先问题可用于解决动态根树中的可达性问题,因此我想您也将对以下内容感兴趣:Alstrup和Thorup提出的在动态树中查找最近的公祖的最佳算法。本文为指针链接上的链接和 nca个查询给出了的时间范围。 O(n+mloglogn)nm


感谢您的参考。最接近的共同祖先问题当然可以解决树木中的可达性。您链接到的论文描述了增量树,其中所有操作都在时间内进行。我想知道是否还可以改进它与全动态树的配合使用。O(lglg(n))
2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.