具有O(1)插入和O(log(n))搜索复杂度的数据结构?

时间:2016-11-05 12:36:21

标签: algorithm data-structures

是否有可提供 O(1)的数据结构 - 即常量 - 插入复杂度和 O(log(n))搜索复杂性即使在最坏的情况下

排序后的矢量可以进行 O(log(n))搜索,但是插入将采用 O(n)(事实上我并不总是插入元素在前面或后面)。而列表将执行 O(1)插入,但不能提供 O(log(n))查找。

我想知道是否可以实现这样的数据结构。

3 个答案:

答案 0 :(得分:2)

是的,但你必须以两种方式改变规则:

1)您可以使用具有O(1)插入和O(1)搜索的结构(例如CritBit树,也称为bitwise trie)并添加人工成本以将搜索转换为O(log n)。

一个关键字树就像二进制radix tree一样。它通过沿着键的位(例如32位)行走来存储键,并使用该位来决定是在每个节点处向左('0')还是向右('1')导航。搜索和插入的最大复杂度都是O(32),它变为O(1)。

2)我不确定这是否是严格理论意义上的O(1),因为只有当我们限制值范围(比如32位或64位)时O(1)才有效,但对于实际目的,这似乎是一个合理的限制。

请注意,在插入可能的密钥排列的重要部分之前,感知的性能将为O(log n)。例如,对于16位密钥,您可能必须插入2 ^ 16 = 65563个密钥的重要部分。

答案 1 :(得分:0)

  

我想知道是否可以实现这样的数据结构。

恐怕答案是肯定的。

搜索确定,不插入

当我们查看二进制搜索树,B树,红黑树和AVL树等数据结构时,它们的平均搜索复杂度为O(log N),但同时平均插入复杂度相同为O(log N)。原因很明显,搜索将跟随(或导航)插入发生的相同模式

插入确定,搜索不

单一链接列表,双向链表等数据结构的平均插入复杂度为O(1),但再次在Singly和Doubly LL中搜索是痛苦的O(N),只是因为他们没有有任何基于索引的元素访问支持

问题的答案在于Skiplist实施,这是一个链接列表,平均需要O(log N)才能插入(预计列表会在O(1)中插入)

在结束笔记时,Hashmap非常接近以满足快速搜索和快速插入要求以及巨大空间的成本,但如果可怕地实现,则可能导致{{1}的复杂性用于插入和搜索。

答案 2 :(得分:0)

(至少在模型中,存储在数据结构中的元素只能与订单进行比较;散列对最坏情况的时间范围没有帮助,因为可能存在一次大的碰撞)

假设每次插入最多需要进行c次比较。 (哎呀,让我们假设n个插入最多需要c * n比较。)考虑一个插入n个元素然后查找一个元素的对手。我将描述一种对抗策略,在插入阶段,强制数据结构具有Omega(n)元素,给定到目前为止进行的比较,可以按任何方式对其进行排序。然后可以强制数据结构搜索这些元素,这些元素相当于未排序的列表。结果是查找具有最坏情况运行时间Omega(n)。

对手的目标是尽可能少地提供信息。元素分为三组:赢家,输家和未知。最初,所有元素都在未知组中。当算法比较两个未知元素时,任意选择一个成为赢家而另一个成为输家。获胜者被视为大于失败者。同样地,未知输家,未知赢家和输家赢家比较通过将其中一个元素指定为胜利者而另一个元素成为输家来解决,而不改变现有的指定。剩下的情况是失败者和赢家 - 赢家比较,这是递归处理的(因此获胜者组有一个赢家 - 未知子组,赢家 - 赢家子组和赢家 - 输家子组)。通过平均参数,由于至少n / 2个元素被比较最多2 * c次,所以存在大小至少n / 2/3 ^(2 * c)= Omega(n)的子子...子组。可以通过先前的比较来验证这些元素都没有排序。