在我的程序中,我需要从一个优先队列中删除一个不在顶部的元素。这可以做到吗?如果不能,请提供一种方法来实现,除了创建自己的堆之外。
通过继承,可以自定义标准的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()) {
return false;
}
if (it == this->c.begin()) {
// deque the top element
this->pop();
}
else {
// remove element and re-heap
this->c.erase(it);
std::make_heap(this->c.begin(), this->c.end(), this->comp);
}
return true;
}
};
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
make_heap
不是必需的。 - klaus triendltemplate<typename T, class Container=std::vector<T>, class Compare=std::less<typename Container::value_type>> class custom_priority_queue : public std::priority_queue<T, Container, Compare>
- Manfred Urbanmake_heap
是不必要的吗?我的猜测是,只有在堆完全排序的情况下,make_heap
才是不必要的,但这并不是现实情况。 - Aelian最佳解决方案是使用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);
del_pq
是处理STL的优先队列删除的一个巧妙小技巧。将所有要删除的值插入其中。当从原始优先队列中弹出值时,请检查del_pq
的最高优先级是否与我们想要删除的相匹配。如果匹配,则从原始优先队列中删除该值。O(logN)
。Pradip和MASh花费时间实现了删除操作。
但是,如果时间复杂度对您很重要,我建议您使用哈希最小堆。
哈希表存储值指针,指针指向一个最小堆。
这意味着您可以在最小堆中花费O(1)的时间找到值,并在O(log(n))的时间内删除(通过sift-up或sift down)元素。
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);
}
vector<type> tempQ
呢? - kevin
set
可以做到。快速删除任意元素?set
也可以做到。 - Benjamin Lindley*mySet.begin()
和*mySet.rbegin()
的翻译如下:由于set是有序的,所以第一个和最后一个元素分别为最小和最大。 - Igor Tandetnik