更改向量中的值后,make_heap是否按预期工作?

时间:2016-11-13 22:42:59

标签: c++ algorithm sorting c++11 heap

我试图使用make_heap来实现Dijkstra的算法,其中(希望)按递减值顺序对向量进行排序以便建立优先级队列,但由于某种原因,如果我改变了一个值并且我不明白为什么,那么排序会出错。

代码:

#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] = 0更改为heap.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 

它可能是什么?提前谢谢。

2 个答案:

答案 0 :(得分:2)

C ++标准未指定标准库应如何实现Heap。所以你不应该期待具体的安排。 C ++标准仅指定行为。

TL; DR;

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

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

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

heap[0] = 0;

甚至:

heap.push_back(0)

答案 1 :(得分:1)

要成为有效的堆,所有i的堆[i]&lt; = heap [(i - 1)/ 2]&gt; 0

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