改变vector中的值后,Make_heap没有按预期工作

make_heap not working as expected after changing value in vector?

本文关键字:heap 工作 Make vector 改变      更新时间:2023-10-16

我试图实现Dijkstra的算法与堆使用make_heap,这(希望)排序在减少值顺序的矢量为了使优先级队列,但由于某种原因排序得到所有错误,如果我改变一个值,我不知道为什么。

代码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
    vector<float> heap;
    for(int i=0;i<5;i++) heap.push_back(1e9);
    heap[0] = 0; // <=== this is a problem for make_heap
    for(int i=0;i<heap.size();i++) cout << heap[i] << ' ';
    cout << endl;
    make_heap(heap.begin(),heap.end());
    for(int i=0;i<heap.size();i++) cout << heap[i] << ' ';
    cout << endl;   
    return 0;
}
输出:

Success time: 0 memory: 3468 signal:0
0 1e+09 1e+09 1e+09 1e+09 
1e+09 1e+09 0 1e+09 1e+09 

一个有趣的事情是,如果我改变heap[0] = 0heap.push_back(0)之前推其他元素的排序工作完美。

输出:

Success time: 0 memory: 3468 signal:0
0 1e+09 1e+09 1e+09 1e+09 1e+09 
1e+09 1e+09 1e+09 1e+09 1e+09 0 

会是什么呢?

c++标准没有指定标准库应该如何实现堆。所以你不应该期待一个具体的安排。c++标准只指定了行为。

TL;博士;

heap[0] = 0heap.push_back(0)之间存在差异。前者不会改变容器的大小,而后者会。奇数/偶数大小的容器的堆表示可能不同;没关系,我们想要的只是在使用适当的函数访问它时的堆行为。


同样,无论何时使用std::make_heap之类的函数,都应该使用其关联函数(std::push_heapstd::pop_heap)来访问容器(这保证维护容器的堆属性)。

对它的任何其他修改都可能导致容器失去堆属性。这包括:

heap[0] = 0;

甚至:

heap.push_back(0)

对于所有i> 0的堆,heap[i] <= heap[(i - 1)/2]是有效的。

在这两种情况下,make_heap()都在创建一个有效的堆。第一个有5个元素,第二个有6个。我不明白你的部分问题,但它们似乎与make_heap()无关。