结构类似优先级队列,但具有类似下界的内容
Structure like priority queue but with something like lower bound
我想要一个结构来存储(例如)数字,我可以在其中插入和删除元素,我的结构始终保持排序(就像优先级队列一样),但有可能知道给定数字的位置,以及对数时间内的每一次操作。
也许使用lower_bound、upper_bound,或者只是二进制搜索,但在priority_queue中,阻碍我进行二进制搜索的是,我无法访问带有索引的元素,只能访问第一个索引。
我认为您正在寻找一个订单统计树,一个支持时间O(logn)中所有常规BST操作的增强BST,以及另外两个:
- rank(elem):返回elem将在排序序列中占据哪个索引
- index(k):给定一个索引k,返回排序序列中该索引处的元素
上述两个操作在O(logn)时间内运行,速度极快。
您可以将订单统计树视为优先级队列。插入与正常的BST插入一样工作,要提取最低/最高的元素,只需从树中删除最小/最大的元素,您只需沿着树的左或右脊椎向下走,就可以在时间O(logn)内完成这一操作。
优先级队列不会按顺序排列。至少,不是典型的。优先级队列使您可以快速获得序列中的下一个项目。但是,您无法有效地访问队列中的第5个项目。
我知道有三种不同的方法可以建立一个优先级队列,在这个队列中你可以通过密钥有效地访问项目:
- 使用平衡的二进制搜索树来实现队列。尽管所有操作都是O(logn),但典型的运行时间比二进制堆慢
- 将堆优先级队列实现为跳过列表。这是一个不错的选择。我看到一些人报告说,跳过列表优先级队列的性能优于二进制堆。搜索[C++跳过列表]会返回许多实现
- 我所说的索引二进制堆也可以。基本上,您将散列映射或字典与二进制堆结合在一起。映射按键进行索引,其值包含堆数组中项的索引。这样的东西不难建造,而且非常有效
- 仔细想想,你可以制作任何类型堆的索引版本
您有很多选择。我自己也很喜欢跳过列表,但你的里程数可能会有所不同。
正如我所指出的,索引二进制堆是一种混合数据结构,它维护一个字典(哈希图)和一个二进制堆。简要介绍它的工作原理:
dictionary键是用于查找放入堆中的项的字段。该值是一个整数:堆中该项的索引。
堆本身是一个在数组中实现的标准二进制堆。唯一的区别是,每次将项从堆中的一个位置移动到另一个位置时,都会更新它在字典中的位置。因此,例如,如果交换两个项,则不仅要交换数组中的项本身,还要交换它们在字典中存储的位置。例如:
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
}
这是对标准二进制堆实现的一个非常简单的修改。每次移动项目时,您只需要小心更新位置。
您也可以使用基于节点的堆来实现这一点,如Pairing堆、Fibonacci堆、Skew堆等。
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 按对象的特定方法按升序排列的C++优先级队列
- 使用2个键的cpp-stl::优先级队列排序不正确
- 为什么我需要C++中不同的排序格式来对这个USACO代码上的数组和优先级队列进行排序
- 打印优先级队列
- 带自定义比较器的最小优先级队列
- 优先级队列自定义比较器
- 排序数组优先级队列
- 更改运行时优先级队列的排序功能
- 优先级队列构造函数的工作
- 实现优先级队列
- 优先级队列功能比较
- 在C++中打印对的优先级队列的所有值时出现问题
- 使用堆的优先级队列,具有相同键的值不遵循 FIFO(先进先出)
- 为什么某些 STL 容器(堆栈、队列、优先级队列)不支持迭代器?
- 是否可以使用简单队列创建优先级队列
- 如何在 c++ 中创建对的优先级队列.这会弹出具有最小值的元素.默认的弹出最大值
- Cython中带有自定义比较器的优先级队列
- 优先级队列比较器[C++].
- asio::io_service 具有多个线程的优先级队列处理