【问题标题】:is there a data structure with O(1) insertion time which also maintains sorted order?是否有一个 O(1) 插入时间的数据结构也保持排序顺序?
【发布时间】:2021-06-23 14:43:23
【问题描述】:

哈希表可以在 O(1) 中插入,但它们没有排序。

BST 维护一个排序(可以使用前序遍历),但插入是 O(logN)。

是否有任何数据结构:

  1. 保证 O(1) 插入
  2. 保持对元素的排序?

如果没有,是否有证据证明这种数据结构不存在? 谢谢

【问题讨论】:

  • @ggorlen Python 字典不保持“排序”顺序,它们保持插入顺序。那是相当不同的。如果您只想在保持插入顺序的同时进行 O(1) 插入,那将是微不足道的;标准列表数据结构就是这样做的,appendpush 在末尾插入一个值。

标签: data-structures binary-search-tree hashtable


【解决方案1】:

您可以为这个 O(1) 换取更多空间。如果值域是整数,例如从 0 到 N-1, 那么你可以拥有一个

// (In Java)
int[] valueToFrequency = new int[N];

void insert(int value) {
    ++valueToFrequency[value];
}

对于 N 值:O(N)

困难(除了值映射和基于 0 的索引)是数组是稀疏的:许多零。 因此输出很慢。

对于唯一值(正如“哈希表”所暗示的那样),可以在 Java 中使用 BitSet。这在输出(nextSetBit)上也快一点。

// (In Java)
BitSet valueToFrequency = new Bitset(N);

void insert(int value) {
    valueToFrequency.set(value);
}

【讨论】:

  • 啊,我明白了。所以这通过使用类似于基数排序的概念绕过基于比较的排序的nlogn下限?大概,您还需要一种将所有元素转换为整数的方法?
  • 上面的值域是0..(N-1),用这个值作为索引,得到一个巨大的排序稀疏数组,BitSet是最好的表示。可以将域 -A..+B 转换为 0..(A+B)。这不是一个非常优雅的解决方案。基数排序是 O(N) 或 O(N.w),其中 w 是位数,即 log(N)。因此,尽管基数排序被认为是线性的 - O(N),但我个人认为它与 O(N.log N) 的其他排序没有太大区别。上面有 O(N): N 次用 O(1) 插入一个值。缺点是输出。
【解决方案2】:

在一般情况下,这样的数据结构是不可能的,因为您可以使用它通过 O(n) 比较操作对序列进行排序,只需将序列元素一个接一个地插入其中即可。很容易证明 Ω(n log n) 是 number of comparisons required to sort a list 的下限,因此插入到“保持排序顺序”的数据结构中每个元素必须至少花费 Ω(log n) 时间。

这里我假设可以迭代数据结构以输出排序列表,而无需进行任何额外的比较。如果仅需要额外的比较来迭代数据结构的内容,那么可以公平地说数据结构不会在内部“维护”排序顺序。如果您不介意遍历大小为 n 的集合需要 O(n log n) 时间,那么您可以使用未排序列表作为数据结构,插入时间为 O(1)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多