完美列表结构?

时间:2014-02-09 04:43:16

标签: data-structures

理论上可能有一个具有

的数据结构

O(1)访问,插入,删除时间

和动态长度?

我猜测还没有发明过,或者我们完全放弃使用数组和链接列表(单独使用),而是选择使用其中之一。

是否有证据证明这是不可能发生的,因此访问时间,插入时间和删除时间(如能量守恒)之间的某种关系表明,如果其中一个时间变得不变,另一个时间必须是线性的沿着那个。

4 个答案:

答案 0 :(得分:3)

当前架构中不存在此类数据结构。

非正式推理:

  • 要获得比O(n)时间更好的插入/删除,您需要某种树数据结构
  • 要获得O(1)随机访问权限,您无法负担遍历树

您可以做的最好的事情就是获得O(log n)所有这些操作。这是一个相当不错的折衷方案,并且有很多数据结构可以实现这一目标(例如Skip List)。

您还可以使用具有高分支因子的树来“接近O(1)”。例如,Clojure的持久数据结构使用32路树,它可以为您提供O(log32 n)个操作。出于实际目的,这与O(1)非常接近(即,您可能在真实世界的集合中遇到的n的实际尺寸)

答案 1 :(得分:2)

如果您愿意以摊销的常数时间结算,则将其称为哈希表。

答案 2 :(得分:1)

最接近的数据结构是B + -tree,它可以轻松回答诸如“k项目是什么”之类的问题,但在O(log(n))时间内执行必要的操作。值得注意的是,迭代(以及关闭元素的访问),特别是使用游标实现,可以非常接近数组速度。

  • 将一个额外的因子C作为我们的“块大小”(应该是高速缓存行的倍数),我们可以获得类似插入时间〜log_C(n) + log_2(C) + C的内容。对于C = 256和32位整数,log_C(n) = 3表示我们的结构为64GB。除此之外,您可能正在寻找混合数据结构,并且比本地数据结构更担心网络缓存效应。

答案 3 :(得分:0)

让我们先列举您的要求,而不是先提到一个可能的数据结构。

基本上,你想要......的常量操作时间。

  • 使用
    • 如果您确切知道您要查找的实体的位置,则很容易实现。散列值或索引位置可用于唯一标识实体,并提供持续访问时间。 这种方法的主要缺点是您无法将真正相同的实体置于同一数据结构中。

  • 插入
    • 如果您可以在列表的最后插入而不必遍历它,那么您可以实现持续的访问时间。 使用这种方法的主要缺点是你必须始终有一个指向列表末尾的引用,必须在更新时修改(理论上应该是一个恒定的时间)操作也是如此)。如果您决定对每个值进行哈希以便以后快速访问,那么计算哈希值并将其添加到某些支持结构以进行快速索引的成本是很高的。

  • 删除时间
    • 这里的主要原则是不能有太多的活动部件;我正在一个固定的,明确定义的位置删除。像StackQueueDeque这样的内容可以提供大部分,因为他们只删除一个元素,无论是在LIFO还是FIFO订单。 使用这种方法的主要缺点是您无法扫描集合以查找其中的任何元素,因为这将花费O(n)时间。如果您正在使用散列的路线,您可能可能在O(1)时间内以O(n)存储空间的多个(用于散列)为代价。

  • 动态长度
    • 如果您正在链接引用,那么这不应该是一个大问题; LinkedList已经有一个内部Node类。 这种方法的主要缺点是你的记忆不是无限的。如果你采用散列的方法,那么你需要散列的东西越多,碰撞的概率就越高(这会让你超出O(1)时间,并且你将更多的东西放入一个摊销的O(1) )时间)。

通过这种方式,实际上没有单一的,完美的数据结构可以为您提供动态长度的绝对恒定的运行时性能。我也不确定通过为这样的事情编写证据而提供的任何价值,因为数据结构的一般用途是利用其积极因素并与其否定一起生活(在散列集合的情况下:喜欢访问时间,没有重复是一个ouchie)。

虽然,如果你愿意接受一些摊销的表现,一套可能是你最好的选择。