结构像优先级队列,但有下限等

时间:2017-11-18 20:42:26

标签: c++ c++11 priority-queue lower-bound

我想要一个结构来存储(例如)我可以插入和删除元素的数字,我的结构始终保持排序(如优先级队列)但是可以知道给定数字的位置,以及对数的每个操作时间。

也许使用lower_bound,upper_bound或者只是二进制搜索,但是在priority_queue中阻止我进行二分查找的是我无法访问带索引的元素,只能访问第一个元素。

2 个答案:

答案 0 :(得分:1)

优先级队列不会按顺序排列。至少,通常不是。优先级队列使您可以快速获取序列中的下一个项目。但是你无法有效地访问队列中的第5项。

我知道有三种不同的方法来构建优先级队列,您可以通过密钥有效地访问项目:

  • 使用平衡二叉搜索树来实现队列。虽然所有操作都是O(log n),但典型的运行时间比二进制堆慢。
  • 将堆优先级队列实现为skip list。这是一个不错的选择。我见过有人报告跳过列表优先级队列优于二进制堆。搜索[C ++跳过列表]将返回许多实现。
  • 我称之为索引二进制堆也可以。基本上,您将哈希映射或字典与二进制堆结合。映射由key索引,其值包含堆数组中项的索引。这样的事情并不难建立,而且非常有效。
  • 想想看,你可以制作任何类型堆的索引版本。

您有很多选择。我喜欢跳过清单,我自己,但你的里程可能会有所不同。

正如我所指出的,索引二进制堆是一个混合数据结构,它维护一个字典(哈希映射)和一个二进制堆。简要说明它的工作原理:

字典键是用于查找放入堆中的项目的字段。该值是一个整数:堆中该项的索引。

堆本身是在数组中实现的标准二进制堆。唯一的区别是每次在堆中将项目从一个地方移动到另一个地方时,都会更新其在字典中的位置。因此,例如,如果交换两个项目,则不仅需要交换数组中的项目本身,还要交换存储在字典中的项目。例如:

heap is an array of string references
dict is a dictionary, keyed by string

swap (a, b)
{
    // swap item at heap[a] with item at heap[b]
    temp = heap[a]
    heap[a] = heap[b]
    heap[b] = temp
    // update their positions in the dictionary
    dict[heap[a]] = b
    dict[heap[b]] = a
}

这是对标准二进制堆实现的非常简单的修改。您每次移动项目时都必须小心更新位置

您也可以使用基于节点的堆来完成此操作,例如配对堆,Fibonacci堆,偏斜堆等。

答案 1 :(得分:1)

我认为你正在寻找一个order statistics tree,一个增强的BST,它支持所有常规BST操作的时间O(log n),以及另外两个:

  • rank(elem):返回索引elem在排序序列中占据的位置。
  • index(k):给定索引k,返回排序序列中该索引处的元素。

上述两个操作在O(log n)时间运行,使得它们非常快。

您可以将订单统计信息树视为优先级队列。插入作为普通的BST插入工作,并提取最低/最高元素,您只需从树中删除最小/最大元素,您可以通过向下走树的左或右脊来及时做O(log n)