提取priority_queue的最后一个元素

时间:2016-05-31 10:19:09

标签: 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。因此,为了在访问第三环邻域后停止此过程,我必须跟踪当前环的最后一个元素。

1 个答案:

答案 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"。我自己从未使用过该结构,因此我不会推荐一个特定的结构。