我使用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。因此,为了在访问第三环邻域后停止此过程,我必须跟踪当前环的最后一个元素。
答案 0 :(得分:2)
"显而易见"方法是存储最后(最小)元素的副本以及priority_queue
。跟踪此操作的额外工作与添加到优先级队列的元素数量成正比,而您的解决方法是在您调用它时队列大小为N log(N),所以请选择。
每当您pop
时,根据定义,如果pop
导致队列为空,您只能删除最后一个值,因此您不必担心更新任何内容{ {1}}。
每当您pop
到优先级队列时,将推送的值与当前最小值进行比较,并在必要时将其替换。同样适用于push
。
如果您想真正想要,可以通过编写自己的容器适配器emplace
来呈现。或者可能是一个较短的名字。
如果你需要访问实际的元素,而不是它的副本,那么你就会遇到一个问题,priority_queue_that_additionally_accesses_the_min_value
本身会在你不看的时候在内部移动东西,所以你可以&只需保持指向最小值的指针即可。在智能指针中包含元素可能会解决这个问题,当然你需要为priority_queue
提供一个比较智能指针的比较器。
最后,有一个"双端优先级队列"。这将允许您在两端有效地移除,而不是从一端有效地移除并检查两者。它不是标准的C ++,而是查找必要的结构和算法并自己实现,或者搜索"双端优先级队列"的C ++实现。或者" min / max heap"。我自己从未使用过该结构,因此我不会推荐一个特定的结构。