我很好奇Boost是否提供优先级队列实现,它还支持在时间O(log n)中查找元素?
我可以通过使用Boost Fibonacci堆实现此功能,并将句柄与其索引一起存储在std :: map中,并在堆插入时更新此信息,但我希望有一个已经提供此功能的堆版本
注意:我删除了以前版本的问题,因为它太模糊了。
答案 0 :(得分:2)
如果你不介意在空间和插入时间上有(可观的?)开销,你可以在这里使用多索引容器。
对于一个想法,这是一个使用Boost Multi-Index在Boost Asio之上执行优先级队列实现Active Object模式的示例:
应该注意的是,多指数让你在同一个容器上指定任意数量的二级/辅助指数
答案 1 :(得分:1)
您可以使用
(multi)set<pair<priority, item> >
multimap<priority, item>
(multi)set<item>
。存储元素。
如果您需要O(1)
访问top元素,您可以使用由上述类似集合结构支持的自有容器,并将迭代器存储到第一个元素并在需要时更新它。
我不确定这种解决方案是否比其他方法更好,但它可以快速实施和测量。集合上的大多数操作都是O(n*log(n))
,就像在优先级队列上一样,但总体上set
应该更慢,因为它散布在内存中。
答案 2 :(得分:0)
在不牺牲优先级队列操作的渐近性能的情况下,在不到线性的时间内在优先级队列中查找元素的唯一方法是在每个优先级队列操作时跟踪每个元素的位置。
我找到的唯一提供必要功能的库是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许可下的独立普通C.