如何在弹出操作期间优先级队列比较和maintIn堆属性

时间:2016-01-29 19:01:53

标签: c++ stl heap priority-queue

我正在处理优先级队列,我想检查在弹出操作期间如何维护堆属性。这是我的代码。

#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
我错在哪里?

1 个答案:

答案 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

我们继续这样,直到堆为空。我留给你弄清楚剩下的。希望这会有所帮助。