接着再讲另一种容器-。主要包括建堆、维护堆和堆排序。以大根堆为例,图解如下:

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 1
    for (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 4
    for (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 1
    cout<<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 8
    for (int i =0 ;i<vec.size();i++)
    {
        cout<<vec[i]<<" ";
    }
    cout<<endl;
    return 0;
}

更多推荐