这是一个有趣的问题:
假设我们有一组A
,允许以下内容:
- 插入x
- Find-min x
- 删除A
中的第n个插入元素
创建一个数据结构,以在对数时间内允许这些。
最常见的解决方案是使用堆。 AFAIK,带有减少键的堆(基于值 - 通常是添加元素时的索引)保留一个表Pos[1...N]
表示i
- 添加的值现在在索引{{1因此,它可以找到减少O(1)的关键。有人可以证实这一点吗?
另一个问题是我们如何用STL容器解决问题?即Pos[i]
,sets
或maps
。我找到的部分解决方案是拥有一个带索引的优先级队列,但按这些索引的值排序。即priority queues
是我们按插入顺序添加的元素。基于A[1..N]
的比较,pri-queue
1..N
(A[i],A[j])
。现在我们保留一个包含已删除索引的表,并验证是否删除了最小值索引。不幸的是,Find-min与no略有成正比。已删除的值。
还有其他想法吗?
现在我想到了如何制定一个更普遍的问题。
使用<key, value>
元素创建类似于multimap的数据结构。 Keys are not unique. Values are.
插入,找到一个(基于键),查找(基于值),删除一个(基于键)和删除(基于值)必须允许O(logN)。
或许有点奇怪,这可以通过手动实现的二进制搜索树进行修改:对于每个节点操作,使用指向节点的新指针更新散列表或基于值的映射。
类似于严格排序的std::set
(如果值按键值相等),并且值为哈希表,给予包含该值的元素的迭代器。
可能std::set
和Chong Luo描述的(std :: map / hash表)。
答案 0 :(得分:2)
您可以使用两个容器的组合来解决您的问题 - 在其中添加每个连续元素和一组的向量:
我认为你无法用STL中的一个容器解决问题。但是,有一些数据结构可以解决您的问题:
Skip list - 可以在常数时间内找到最小值,并以摊销复杂度O(log(n))执行其他两个操作。它实施起来相对容易。
Tiered vector易于实现,将在常量时间执行find_min,其他两个操作在O(sqrt(n))
当然你提出的方法 - 编写自己的堆,跟踪其中第n个元素的位置。