在我的程序中,我需要从不在顶部的优先级队列中删除一个元素。可以这样做吗?如果没有,请提出一种方法,除了创建自己的堆。
问问题
70231 次
5 回答
56
标准priority_queue<T>
可以通过继承来定制。它具有受保护的成员c
,comp
并且可以在后代类中引用。
template<typename T>
class custom_priority_queue : public std::priority_queue<T, std::vector<T>>
{
public:
bool remove(const T& value) {
auto it = std::find(this->c.begin(), this->c.end(), value);
if (it != this->c.end()) {
this->c.erase(it);
std::make_heap(this->c.begin(), this->c.end(), this->comp);
return true;
}
else {
return false;
}
}
};
void main()
{
custom_priority_queue<int> queue;
queue.push(10);
queue.push(2);
queue.push(4);
queue.push(6);
queue.push(3);
queue.remove(6);
while (!queue.empty())
{
std::cout << queue.top();
queue.pop();
if (!queue.empty())
{
std::cout << ", ";
}
}
}
输出:
10、4、3、2
于 2016-04-19T07:40:40.360 回答
30
最好的解决方案是使用 std::set。集合提供了允许它同时用作最小/最大堆(或优先级队列)的方法。
std::set<int> pq;
//accessing the smallest element(use as min heap)
*pq.begin();
//accessing the largest element (use as max heap)
*pq.rbegin();
此外,集合还允许随机删除。
//to delete the integer '6'
auto it = pq.find(6);
pq.erase(it);
于 2019-04-17T19:28:52.870 回答
9
一个巧妙的小技巧来处理优先队列 STL 的删除 - 使用另一个优先队列,比如del_pq
. 继续向其中插入所有删除值。当您从原始优先级队列中弹出值时,请检查 top ofdel_pq
并查看我们是否要删除它。如果匹配,则从原始priority_queue 中删除该值。
此方法实现了一种延迟删除原始优先级队列中的值的方法。可以占用两倍的内存,但平均删除和插入仍然存在O(logN)
。
于 2020-05-10T15:24:44.973 回答
5
Pradip 和 MASh 牺牲了时间来实现删除操作。但是如果时间复杂度对你很重要,我建议你使用 hash min_heap。哈希表存储值指针,指针指向 min_heap。这意味着您可以花费 O(1) 时间来查找 min_heap 和 O(log(n)) 中的值来删除(向上筛选或向下筛选)元素。
于 2016-10-20T08:23:06.420 回答
-4
请注意 以下方法可以解决问题,但不是优化的解决方案。对于优化的方法,请检查其他答案。
让你想删除priority_queue<type> Q
. 然后你可以这样做:
vector<type> tempQ;
int i = 0;
int n = 5;
type t;
// backup n-1 items
while(i < n-1)
{
tempQ.push_back(Q.top());
Q.pop();
i++;
}
// remove the nth item
Q.pop();
// restore the backed up items
i = 0;
while(i < n-1)
{
t = tempQ[i++];
Q.push(t);
}
于 2016-01-27T19:28:04.907 回答