使用 STL 容器在 logN 中插入、查找最小(键)和删除(基于值)功能

Insert, find-min(key) and delete(based on value) functionality in logN with STL containers?

本文关键字:删除 功能 于值 查找 STL logN 插入 使用      更新时间:2023-10-16

这里有一个有趣的问题:假设我们有一个允许以下内容的A

  • 插入 x
  • 查找分钟x
  • 删除 A 中插入的第 n 个元素

创建一个数据结构以允许在对数时间内执行这些操作。

最常见的解决方案是使用堆。AFAIK,带有递减键的堆(基于一个值 - 通常是添加元素时的索引(保留一个表,Pos[1...N]意味着第 i 个添加值现在位于索引 Pos[i] 上,因此它可以找到在 O(1( 中减少的键。有人可以证实这一点吗?

另一个问题是我们如何解决STL容器的问题?即使用setsmapspriority queues。我发现的部分解决方案是有一个带有索引的优先级队列,但按这些索引的值排序。J.F. A[1..N]是我们按插入顺序添加的元素。 pri-queue 基于(A[i],A[j])比较的1..N .现在我们保留一个包含已删除索引的表,并验证是否删除了最小值索引。不幸的是,Find-min 与 no 略成正比。已删除的值。有什么其他想法吗?

现在我想到如何制定一个更普遍的问题。创建类似于包含<key, value>元素的多重映射的数据结构。 Keys are not unique. Values are. 插入、查找一个(基于键(、查找(基于值(、删除一个(基于键(和删除(基于值(必须允许 O(logN(。

也许有点奇怪,这可以通过手动实现的二叉搜索树进行修改来实现:对于每个节点操作,哈希表或基于值的映射都会使用指向节点的新指针进行更新。

类似于具有严格排序的std::set(如果按值相等的键顺序(,其值上的哈希表为包含该值的元素提供迭代器。

可以使用 std::set 和 (std::map/hash table(,如 Chong Luo 所描述的那样。

您可以使用两个容器的组合来解决问题 - 一个向量,您可以在其中添加每个连续的元素和一个集合:

  • 您可以使用该集合执行find_min而
  • 当您在向量中插入执行push_back元素并插入集合中时
  • 当您删除第 n 个元素时,您会在向量中看到它的值并将其从集合中删除。在这里,我假设执行删除第 n 个元素后元素的数量不会改变。

我认为仅使用STL的一个容器无法解决问题。但是,有一些数据结构可以解决您的问题:

跳过列表 - 可以在常量时间内找到最小值,并将执行其他两个具有摊销复杂度 O(log(n(( 的操作。它相对容易实现。

分层向量易于实现,可以在恒定时间内执行find_min,并在 O(sqrt(n(( 中执行其他两个操作

当然,还有你提出的方法 - 编写你自己的堆来跟踪其中的第 n 个元素的位置。