C++ 如何合并两个优先级队列?

C++ 如何合并两个优先级队列?,c++,c++11,C++,C++11,我有两个priority\u queue和float如下: std::priority_queue<float> queue1; std::priority_queue<float> queue2; 有没有一种方法可以在不使用辅助数据结构的情况下合并priority\u queue?priority\u queue是一个容器适配器,而不是常规的标准容器。特别是,它不提供begin()和end()成员函数。因此,您必须将元素从一个队列中弹出并推入另一个队列: while

我有两个
priority\u queue
float
如下:

std::priority_queue<float> queue1;
std::priority_queue<float> queue2;

有没有一种方法可以在不使用辅助数据结构的情况下合并
priority\u queue

priority\u queue
是一个容器适配器,而不是常规的标准容器。特别是,它不提供
begin()
end()
成员函数。因此,您必须将元素从一个队列中弹出并推入另一个队列:

while (!queue2.empty())
{
    queue1.push(queue2.top());
    queue2.pop();
}

除了Andy的答案之外,一个重要的优化是始终将较小优先级队列中的元素合并到较大优先级队列中。这可以使用
std::swap

// merge elements into dest from src
template<typename T>
void merge_pq(std::priority_queue<T>& dest, std::priority_queue<T>& src) {
  if (dest.size() < src.size()) {
    std::swap(dest, src);
  }
  while (!src.empty()) {
    dest.push(src.top());
    src.pop();
  }
}
//将元素从src合并到dest
模板
无效合并队列(标准::优先级队列和目的地,标准::优先级队列和src){
if(dest.size()
这可能会产生真正的差异,特别是当两个优先级队列的大小非常不同时


在最近的Facebook黑客杯编程竞赛中,有一个问题要求您将优先级队列合并为更大算法的一部分。如果您没有进行此优化,您的代码将花费太长时间,并且您将无法正确回答问题。这发生在我身上;我的代码在没有这个优化的情况下运行了5分钟,但在比赛结束后添加这个优化时不到10秒。我没有因为这个问题而得到表扬。如果您正在阅读本文并遇到类似问题,希望您会更成功:)

而不是像前面建议的那样逐个处理它们,为了获得更好的性能,您可以从队列中合并它们,然后从合并的容器中构建另一个
优先级队列

// https://stackoverflow.com/a/1385520/8414561
template <class T, class S, class C>
S& Container(std::priority_queue<T, S, C>& q) {
    struct HackedQueue : private std::priority_queue<T, S, C> {
        static S& Container(std::priority_queue<T, S, C>& q) {
            return q.*&HackedQueue::c;
        }
    };
    return HackedQueue::Container(q);
}

int main()
{
    std::priority_queue<int> queue1{std::less<int>{}, {1,2,3,4,5,6,7}};
    std::priority_queue<int> queue2{std::less<int>{}, {10,14,15}};

    auto v1 = std::move(Container(queue1));
    auto v2 = std::move(Container(queue2));

    v1.insert(v1.end(), std::make_move_iterator(v2.begin()), std::make_move_iterator(v2.end()));

    std::priority_queue<int>queue3{std::less<int>{}, std::move(v1)};
    while (!queue3.empty()) {
        std::cout << queue3.top() << std::endl;
        queue3.pop();
    }
}
//https://stackoverflow.com/a/1385520/8414561
模板
S&Container(标准::优先级队列&q){
结构HackedQueue:private std::priority_队列{
静态S和容器(标准::优先级队列和q){
返回q.*&HackedQueue::c;
}
};
返回HackedQueue::Container(q);
}
int main()
{
std::priority_队列队列1{std::less{},{1,2,3,4,5,6,7};
std::priority_队列队列2{std::less{},{10,14,15};
autov1=std::move(容器(队列1));
autov2=std::move(容器(队列2));
v1.insert(v1.end(),std::make_move_迭代器(v2.begin()),std::make_move_迭代器(v2.end());
std::priority_queue3{std::less{},std::move(v1)};
而(!queue3.empty()){

std::cout我担心您将不得不从一个队列中弹出元素并将它们推入另一个队列。标准库不包含合并两个堆的算法。因为
priority\u queue
只是标准库堆算法的包装,所以您没有合并功能。
// https://stackoverflow.com/a/1385520/8414561
template <class T, class S, class C>
S& Container(std::priority_queue<T, S, C>& q) {
    struct HackedQueue : private std::priority_queue<T, S, C> {
        static S& Container(std::priority_queue<T, S, C>& q) {
            return q.*&HackedQueue::c;
        }
    };
    return HackedQueue::Container(q);
}

int main()
{
    std::priority_queue<int> queue1{std::less<int>{}, {1,2,3,4,5,6,7}};
    std::priority_queue<int> queue2{std::less<int>{}, {10,14,15}};

    auto v1 = std::move(Container(queue1));
    auto v2 = std::move(Container(queue2));

    v1.insert(v1.end(), std::make_move_iterator(v2.begin()), std::make_move_iterator(v2.end()));

    std::priority_queue<int>queue3{std::less<int>{}, std::move(v1)};
    while (!queue3.empty()) {
        std::cout << queue3.top() << std::endl;
        queue3.pop();
    }
}