支持按索引和键随机访问、以对数时间插入、删除并保持顺序的数据结构
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我考虑过以下不正确的解决方案:
使用数组:find
、delete
和 insert
仍然是 O(N)
使用数组 + K 的映射来索引:delete
和 insert
仍将花费 O(N) 来移动元素和更新映射
使用链表 + 映射 K 到元素地址:get
和 find
仍将花费 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(logN)):
在数组中的任意位置插入元素 删除任意元素 在任意间隔上查找总和、最小/最大元素等 加法,以任意间隔绘制 以任意间隔反转元素
使用带有隐式键的修改允许您执行除第二个操作之外的所有操作(查找与 K 匹配的元素的索引)。如果我想出一个更好的主意,我会编辑这个答案:)
【讨论】:
treap 在渐近上并不比一般的平衡二叉搜索树好。 @devouredelysium 你是对的,比较get或delete操作并没有更好,但它不能在索引处删除和插入元素,增加或减少其他元素的索引。由于 treap 支持间隔加法,所以这是可能的。实际上,segment tree 也应该这样做以上是关于支持按索引和键随机访问、以对数时间插入、删除并保持顺序的数据结构的主要内容,如果未能解决你的问题,请参考以下文章
O(1) 随机插入/删除和 O(1) 随机访问的数据结构是啥?