Boost:优先级队列,支持在O(log n)时间内找到元素
Boost: Priority Queue which supports finding an element in O(log n) time
我很好奇Boost是否提供优先队列实现,也支持在时间O(log n)中找到元素?
我可以通过使用Boost斐波那契堆实现此功能,并将句柄与其索引一起存储在std::map中,并在堆插入时更新此信息,但我希望堆版本已经提供了此功能。
注:我删除了上一版的问题,因为它太模棱两可了。
如果您不介意(相当大的)空间开销和插入时间,您可以在这里使用多索引容器。
为一个想法,这里有一个例子,使用Boost多索引做一个优先级队列实现活动对象模式在Boost Asio之上:
- boost::asio和Active Object
应该注意的是,Multi-Index允许你在同一个容器上指定任意数量的辅助索引
可以使用
-
(multi)set<pair<priority, item> >
-
multimap<priority, item>
-
(multi)set<item>
与自定义比较器,如果优先级可以很容易地从项目计算。
存储元素。
如果您需要O(1)
访问顶部元素,您可以使用自己的容器,该容器由上面描述的类似set的结构支持,并存储第一个元素的迭代器,并在需要时更新它。
我不确定这个解决方案在性能方面是否比其他方法更好,但它可以快速实现和测量。set上的大多数操作都是O(n*log(n))
,就像在优先级队列上一样,但总的来说set
应该更慢,因为它分散在内存中。
在小于线性时间内找到优先级队列中元素而不牺牲优先级队列操作的渐近性能的唯一方法是跟踪每个元素在每次优先级队列操作中的位置。
我发现唯一提供必要功能的库是libpqueue
,现在可以在这里获得:https://github.com/vy/libpqueue.
使用用户自定义的回调函数cmppri()
, getpri()
, setpri()
, getpos()
, setpos()
,这些函数在每次队列更新时被库调用。
typedef struct {
pqueue_pri_t pri;
void *data;
size_t pos;
} node_t;
和访问器函数,如:
static size_t get_pos(void *a) {
return ((node_t *) a)->pos;
}
static void set_pos(void *a, size_t pos) {
((node_t *) a)->pos = pos;
}
这允许在O(1)
时间内找到节点的位置,以牺牲创建包装器结构和回调调用的开销为代价。如果您需要通过名称(而不是通过node_t指针)查找元素,您可以轻松地使用std::unordered_map
或类似的后端。
libpqueue
是Apache许可下的独立plain C。
- 使用堆查找第K个最大元素的时间复杂性
- 如何在 c++ stl 中获取列表中被推回的元素的地址,在常量时间内?
- 比较向量中的元素时所花费的时间呈指数级增长
- 保持排序的数据结构,允许log N插入时间,并且可以返回我在log N中查找的元素的索引
- 将数组的元素插入映射的时间复杂度是多少?
- Deque 中元素的随机访问如何提供恒定的时间复杂度?
- 我们可以在队列前面以 O(1) 时间复杂度排队一个元素吗?
- 如何在对数时间内访问 c++ std::set 中的第 k 个元素?
- 如何检查 2 个 c++ 数组在 O(1) 或 O(log n) 时间复杂度中是否相同(所有元素都相同,顺序很重要)?
- 包含每个 k 个列表中至少 1 个元素的最小元素范围的时间复杂度
- 在O(1)时间C 中找到堆栈中的最小元素
- 如何检查 O(N) 时间复杂度的多重集中是否有 2 个或更多元素具有相同的值
- 如何恢复注册表项的所有元素?(上次写入时间,类型,值,名称...这是正确的方法吗?
- 从容器中获取随机元素,该容器在恒定时间内没有严格的元素顺序
- 对列表中的任意元素的常量时间访问 (C++)
- 在编译时间检查模板参数类型是否设置或多键,并且容器的元素类型是算术的
- DFS 访问内部的地图元素.时间复杂度
- 为什么我列表中的所有元素都有相同的创建时间
- O(1) 时间平衡二叉搜索时间中的最小/最大元素
- 获取树集 O(1) 时间中的最大元素