c++ - 提取 priority_queue 的最后一个元素

标签 c++ queue priority-queue

我正在使用 std::priority_queue 编写一种算法,计算 3D 网格上数据集的距离函数。初始化队列后,我想将最后一个元素存储在一个单独的变量中,就像您使用 std::queue.back() 一样,但是,当然,这对于优先级队列是不可能的,所以我的解决方法是以下内容:

CellQueue q; //this is the actual priority_queue

//...
//initialization
//...

Cell* last = 0;
CellQueue dummy(q);
while (!dummy.empty()) {
    last = dummy.top();
    dummy.pop();
}

当然有更好的方法来解决这个问题,所以如果有人能展示给我,我会很高兴。

谢谢,

费德里科


编辑

@Sam @Dietmar 计算距离函数 (DF) 的算法以这种方式工作:您用包含至少一个数据集点的网格单元格填充 priority_queue,然后按距离对它们进行排序(在此步骤中为零)按递增顺序排列。然后,对于队列中的每个元素,您访问邻居并为每个邻居计算相对于其父元素的距离。现在,出于效率原因,我只想在数据集周围的窄带上计算 DF。因此,为了在访问第 3 环邻域后停止此过程,我必须跟踪当前环的最后一个元素。

最佳答案

“显而易见”的方法是将最后一个(最小)元素的拷贝与 priority_queue 一起存储。跟踪此问题的额外工作与添加到优先级队列中的元素数量成正比,而您的解决方法是在您调用它时队列大小为 N log(N),因此请自行选择。

每当您pop 时,根据定义,如果pop 导致队列为空,您只能删除最后一个值,因此您无需担心在 pop 上更新任何内容。

每当您推送到优先级队列时,将推送的值与当前最小值进行比较,并在必要时替换它。 emplace 也是如此。

如果你真的想变得很花哨,你可以通过编写你自己的容器适配器来展示它,priority_queue_that_additionally_accesses_the_min_value。或者更短的名称。

如果你需要访问实际的元素,而不是它的拷贝,那么你就会遇到一个问题,因为 priority_queue 本身会在你不注意的时候在内部移动东西,所以你不能只将指针保持在最小值。将元素包装在智能指针中可能会解决这个问题,当然您需要为 priority_queue 提供一个引用智能指针的比较器。

最后,还有“双端优先队列”这种东西。这将使您能够有效地去除两端,而不是有效地从一端去除并检查两端。它不是在标准 C++ 中,而是查找必要的结构和算法并自己实现,或者搜索“双端优先级队列”或“最小/最大堆”的 C++ 实现。我自己从未使用过该结构,因此我不会推荐特定的结构。

关于c++ - 提取 priority_queue 的最后一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37542974/

相关文章:

c++ - 使用 Eclipse 调试时如何在 Linux 中查看 C++ shared_ptr 内容?

c++ - glibc(或 libc6)库版本

python - pybind11 将 python sys.stdout 从 print() 重定向到 C++

hadoop - 在特定队列上运行 sqoop 作业

C++ STL 优先队列排序不正确

c++ - 如何在跳过所有内部实现的同时跳转到 GDB 中 std::function 中的函数?

java - @Async 阻止线程继续,直到其他线程完成

javascript - Javascript 中的异步方法队列

java - 线程中的异常 "main"java.lang.ClassCastException : with priority queue and comparator

Java - 在比较器中进行排序以在优先级队列中使用