【发布时间】:2026-02-03 07:20:06
【问题描述】:
我目前正在实现一些图形算法,并且我想要一个具有斐波那契堆或松弛堆复杂性的容器(特别是我想要至少 O(logN) 用于推送和弹出,O(1) 用于reduce_key)。
如果可能的话(开发和测试开销和时间),我并不热衷于自己实现这一点,我注意到 boost 图形库引用了待处理目录中的几个可能看起来的数据结构。 Relax_heap.hpp 中的轻松堆看起来很贴切,但我不太清楚如何使用它。它具有以下公共功能(为了清楚起见,稍微精确一点):
void push(const value_type& x);
value_type& top();
void pop();
这足够清楚并实现了我想要的推送和弹出。另外还有:
void update(const value_type& x);
void remove(const value_type& x);
我假设我可以使用 update 实现 reduce_key,但我不清楚如何。我的特殊问题是我假设在调用 push 时会复制该值。我觉得我需要的是一个指向堆中值副本的指针,以便我可以通过引用对其进行修改,然后调用 update 将其重新洗牌回到它所属的位置。不过好像没有这样的指针?
任何有一般轻松堆经验的人,或者特别是提升轻松堆经验的人愿意通过解释或漂亮的代码 sn-p 让我摆脱痛苦吗?
谢谢,
亚历克斯
【问题讨论】:
-
我很困惑 --
std::push_heap和std::pop_heap不符合您的要求吗? (我不确定“减少键”是什么意思) -
@Billy:“reduce key”的意思是减少堆中某个元素的值,然后恢复堆结构。这是一个简单(二项式)堆中的
O(log N)时间;其他类型的堆可以在摊销的常数时间内对其进行管理。 -
好的。我想我已经弄清楚了它是如何工作的:你放在轻松堆中的值存储在一个向量中,该向量以存储值的“id”为索引。这不是执行堆排序的值,而是一种明确地从您的元素到它存储在堆中的位置的方法。这样做是为了做一个 reduce 键,你在堆中取你的原始值并保持 id 相同(以便 Relax_heap 可以找到相关的副本),但更改执行排序的值。那会教我使用无证容器... :-)