优先级队列,为什么它仍然打印最后一个元素

时间:2016-12-11 19:26:58

标签: c++ priority-queue

这是我第一次使用队列和队列。这个概念很简单但我在尝试使用STL时遇到了问题。

#include <iostream>
#include <string.h>
#include <queue>
#include <ctime>
#include <stdlib.h>

using namespace std;

int main(){
    srand(time(NULL));
    priority_queue<int> pq;
    for(int i = 0; i < 10; i++){
        int t = rand() % 100;
        cout << "Pushing " << t << " on top of queue." << endl;  
        pq.push(t);
    }
    while(!pq.empty()){
        cout << pq.top() << " : is on top of queue " << endl;
        pq.pop();   
    }

    if(pq.empty()){
        cout << pq.top() << endl;
        cout << "list is empty" << endl;    
    }
    pq.pop();
    cout << pq.top() << endl;
    return 0;   
}

如果队列为空,我想查看打印的内容,但是当我这样做时,它总是打印最后一个元素。我的输出看起来像这样。

Pushing 58 on top of queue.
Pushing 89 on top of queue.
Pushing 76 on top of queue.
Pushing 38 on top of queue.
Pushing 21 on top of queue.
Pushing 69 on top of queue.
Pushing 25 on top of queue.
Pushing 49 on top of queue.
Pushing 58 on top of queue.
Pushing 59 on top of queue.
89 : is on top of queue 
76 : is on top of queue 
69 : is on top of queue 
59 : is on top of queue 
58 : is on top of queue 
58 : is on top of queue 
49 : is on top of queue 
38 : is on top of queue 
25 : is on top of queue 
21 : is on top of queue 
21
list is empty
21

任何人都可以告诉我为什么会这样。即使列表完全为空,为什么打印21。根据我的直觉,最后一个元素存储在缓冲区中的某个位置,如果队列为空,并且如果有人尝试访问空队列,则打印出该元素。

2 个答案:

答案 0 :(得分:5)

top只能在非空队列上调用。当队列为空时调用它会导致未定义的行为,这意味着任何事情都可能发生。

答案 1 :(得分:0)

通过这个小修改再试一次:

#include <iostream>
#include <cstring>
#include <queue>
#include <ctime>
#include <cstdlib>
#include <memory>

using namespace std;

struct Foo
{
    Foo(int x) : p(std::make_unique<int>(x)) {}
    std::unique_ptr<int> p;
};

std::ostream& operator<<(std::ostream& os, const Foo& f)
{
    return os << *f.p;
}

bool operator<(const Foo& l,const Foo& r)
{
    return *(l.p) < *(r.p);
}


int main()
{
    srand(time(NULL));
    priority_queue<Foo> pq;
    for(int i = 0; i < 10; i++){
        auto t = Foo(rand() % 100);
        cout << "Pushing " << t << " on top of queue." << endl;
        pq.push(std::move(t));
    }
    while(!pq.empty()){
        cout << pq.top() << " : is on top of queue " << endl;
        pq.pop();
    }

    if(pq.empty()){
        cout << pq.top() << endl;
        cout << "list is empty" << endl;
    }
    pq.pop();
    cout << pq.top() << endl;
    return 0;
}

然后让我们讨论一下未定义的行为。