3.序列式容器-heap
接着再讲另一种容器-堆。主要包括建堆、维护堆和堆排序。以大根堆为例,图解如下:
heap:
make_heap();
push_heap();
pop_heap();
sort_heap();
①生成一个大根堆(从第一个非叶子结点开始调整堆)
以vector vec={0,1,2,3,4,8,9,3,5};为例。因为heap底层容器是可以随机访问的如vector,因此找到第一个非叶子结点非常简单,只需要(size/2)-1就可以获取需要调整的索引下标。
生成堆动态调整的过程:

最后结果:

②往堆里面添加值并调整堆
③从堆中弹出值并重新调整堆


堆排序就是重复对每个元素执行③的过程,因为每次弹出堆都会确定一个当前堆的最大值。如此重复下去就会获取一个升序序列,这也就是堆排序的一个完整过程。
可执行代码:
//
// Created by wsk on 25-10-23.
//
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;
int main()
{int a[9] = {0,1,2,3,4,8,9,3,5};vector<int> vec(a,a+9);make_heap(vec.begin(),vec.end());// 生成一个堆 9 5 8 3 4 0 2 3 1for (int i =0 ;i<vec.size();i++){cout<<vec[i]<<" ";}cout<<endl;vec.push_back(7);push_heap(vec.begin(),vec.end());// 往堆里面加入一个元素 9 7 8 3 5 0 2 3 1 4for (int i =0 ;i<vec.size();i++){cout<<vec[i]<<" ";}cout<<endl;pop_heap(vec.begin(),vec.end());// 从堆里弹出一个元素,假弹出放在vec的末尾,重新维护堆 8 7 4 3 5 0 2 3 1cout<<vec.back()<<endl;vec.pop_back();// 真正的把堆里的元素弹出// cout << vec.size() << endl;for (int i =0 ;i<vec.size();i++){cout<<vec[i]<<" ";}cout<<endl;sort_heap(vec.begin(),vec.end());// 堆排序 0 1 2 3 3 4 5 7 8for (int i =0 ;i<vec.size();i++){cout<<vec[i]<<" ";}cout<<endl;return 0;
}
