一、创建堆
make_heap()生成堆,可以有两个参数或三个参数,前两个参数是指向开始元素的迭代器和指向结束元素的下一个元素的迭代器。第三个参数是可选的,可以用仿函数less()和greater()来生成最大堆和最小堆。
vector<int> vec = {2,3,1};
make_heap(vec.begin(),vec.end());
//等价于
make_heap(vec.begin(),vec.end(),less<int>());
这样构建的是最大堆,即堆顶元素vec[0]是最大值,同理:
make_heap(vec.begin(),vec.end(),greater<int>());
构建的是最小堆,即堆顶元素vec[0]为最小值。
二、调整堆
当使用上述的make_heap()建完堆后,如果vector使用push_back()插入数据或pop_back()删除数据后,会破坏最大堆/最小堆的性质,所以需要调整堆,常用push_heap()和pop_heap()两个方法:
1、push_heap()用法:vec先push_back(),后push_heap(),相当于把最后插入的元素10加入之前的堆中再堆排序:
vec.push_back(10);
push_heap(vec.begin(), vec.end(), less<int>());
【注意】这里如果之前是最大堆这里要转成最小堆是会出错的:比如直接push_back()一个元素,再用push_heap()转成最小堆(greater)是无法完成要求的,需要先用make_heap()将vec变为最小堆,再push_back(),然后push_heap();
2、pop_heap()用法:先pop_heap(),vec后pop_back(),pop_heap()的内部逻辑是把堆顶元素(也就是最大值)换到vec的最后一个元素的位置,再对vec中除了最后一个元素的其他元素做堆排序,也就是求出了第二大的元素作为堆顶,然后pop_back()弹出上一个最大值,这样保证了该堆依旧是最大堆。
pop_heap(nums.begin(), nums.end(), less<int>());
nums.pop_back();
【当前求最小几个或者最大的几个这类型题时,要想到用堆!】
具体方法除了上面这种还可以:(都是最小堆,带vector的都是反着的,不带的都是less小greater大)
priority_queue<int, vector<int>, greater<int>> q;
multiset<int,less<int>> s;
第一行的结构用push、pop、top等来处理元素;第二行的结构用insert、erase和迭代器(iter)来处理元素。