支持按索引和键随机访问、以对数时间插入、删除并保持顺序的数据结构

Posted

技术标签:

【中文标题】支持按索引和键随机访问、以对数时间插入、删除并保持顺序的数据结构【英文标题】:Data structure that supports random access by index and key, insertion, deletion in logaritmic time with order maintained 【发布时间】:2017-03-01 08:31:43 【问题描述】:

我正在寻找存储 E = (K, V) 元素的有序列表并在最多 O(log(N)) 时间内支持以下操作的数据结构,其中 N 是元素的数量。内存使用不是问题。

E get(index) // 按索引获取元素 int find(K) //找到K匹配的元素的索引 delete(index) // 删除索引处的元素,后面的元素索引减1 insert(index, E) // 在索引处插入元素,后面的元素索引增加1

我考虑过以下不正确的解决方案:

使用数组:finddeleteinsert 仍然是 O(N) 使用数组 + K 的映射来索引:deleteinsert 仍将花费 O(N) 来移动元素和更新映射 使用链表 + 映射 K 到元素地址:getfind 仍将花费 O(N)

在我的想象中,最后一个解决方案是最接近的,但不是链表,而是一个自平衡树,其中每个节点存储它左侧的元素数量,这将使我们可以在 get O(log(N))。

但是我不确定我是否正确,所以我想问一下我的想象是否正确以及这种数据结构是否有名称,以便我寻找现成的解决方案。

【问题讨论】:

+1 等待答案。我怀疑这是否可能,因为您必须使用键或索引在 O(lg N) 中支持 find(),但结构(我知道)只能按键或索引或值排序...跨度> @shole 同意,我也认为您可以从询问的 4 个操作中选择 3 个操作并支持 O(logn) 而不是全部 4 个。如果在 cs.stackexchange.com 中标记问题可能会更好还有 一个标准的平衡二叉搜索树,每个节点存储其子节点的数量应该足以支持您的所有要求。 【参考方案1】:

我能想到的最接近的数据结构是treaps。

Implicit treap 是对常规 treap 的简单修改,它是一种非常强大的数据结构。实际上,隐式treap可以看作是一个数组,实现了以下过程(在线模式下都是O(logN)O(log⁡N)):

    在数组中的任意位置插入元素 删除任意元素 在任意间隔上查找总和、最小/最大元素等 加法,以任意间隔绘制 以任意间隔反转元素

使用带有隐式键的修改允许您执行除第二个操作之外的所有操作(查找与 K 匹配的元素的索引)。如果我想出一个更好的主意,我会编辑这个答案:)

【讨论】:

treap 在渐近上并不比一般的平衡二叉搜索树好。 @devouredelysium 你是对的,比较get或delete操作并没有更好,但它不能在索引处删除和插入元素,增加或减少其他元素的索引。由于 treap 支持间隔加法,所以这是可能的。实际上,segment tree 也应该这样做

以上是关于支持按索引和键随机访问、以对数时间插入、删除并保持顺序的数据结构的主要内容,如果未能解决你的问题,请参考以下文章

第十一章 关联容器

有效的容器,可保持秩序并快速从任何位置删除元素

ABAP基础篇1 内表

O(1) 随机插入/删除和 O(1) 随机访问的数据结构是啥?

如何在插入点后不重新索引/移动项目的情况下将数据插入到有序、随机可访问的列表中?

380. O 时间插入删除和获取随机元素