我正在处理优先级队列,我想检查在弹出操作期间如何维护堆属性。这是我的代码。
#include <iostream>
#include <queue>
using namespace std;
class g {
public:
bool operator() (int a, int b) {
cout<<a<<" "<<b<<endl;
return (a > b);
}
};
int main() {
priority_queue<int,vector<int>,g> p;
p.push(2);
cout<<"CHECK1"<<endl;
p.push(4);
cout<<"CHECK2"<<endl;
p.push(8);
cout<<"CHECK3"<<endl;
p.push(1);
cout<<"CHECK4"<<endl;
while(!p.empty()) {
cout<<p.top()<<endl;
p.pop();
}
}
输出
CHECK1
2 4
CHECK2
2 8
CHECK3
4 1
2 1
CHECK4
1
8 2
2 4
2
4 8
4
8
这是构建的二进制堆:
1
2 8
4
我看到当弹出1时,它被4替换,然后2被4替换以维护堆属性和二进制堆
2
4 8
当弹出2时,8替换为2,然后4替换为8以保持堆属性,然后4替换为8,当4弹出时,最后8弹出。因此根据我的输出是
CHECK1
2 4
CHECK2
2 8
CHECK3
4 1
2 1
CHECK4
1
4 2
2 8
2
8 4
4
8
我错在哪里?
答案 0 :(得分:0)
第一次致电
p.push(2)
节点2被添加到您的堆中,从而产生
2
/ \
然后我们添加4,它被添加到最左边的开放位置,结果是
2
/ \
4
保持堆性质,因为2&lt; 4,然后我们将8加到下一个开仓位置
2
/ \
4 8
仍然保持堆属性,最后我们添加1。
2
/ \
4 8
/
1
从1&lt;违反了堆属性。 4,所以我们筛选或交换节点4和1,结果是:
2
/ \
1 8
/
4
自1&lt;&lt; 2,结果我们再次筛选,结果:
1
/ \
2 8
/
4
现在回答你的问题。在我们第一次调用top时,我们返回堆的min,在我们的例子中是1.然后我们弹出1,将堆大小减少1,并将堆中的最后一个值复制到root,结果是:< / p>
4
/ \
2 8
因为2&lt; 4,违反了堆属性,这需要筛选,导致:
2
/ \
4 8
我们继续这样,直到堆为空。我留给你弄清楚剩下的。希望这会有所帮助。