STL之堆和堆排序(heap)

STL之堆和堆排序(heap)

使用注意:
  1. 堆函数所在的头文件是#include <algorithm>
  2. 堆函数操作的基础是vector,所以如果要使用heap那么则需要利用vector才能对其进行操作;我们无法创建一个heap,而是先创建一个vector,然后将vector里面的数据按照堆排序。
  3. heap中包含的操作函数一共有4种,分别是:
make_heap( ):建立堆(要么大顶堆,要么小顶堆)
push_heap( ): 在堆中添加元素
pop_heap( ): 在堆中删除元素
sort_heap( ): 堆排序
具体用法
1. 建堆

make_heap(_First, _Last, _Comp)
默认是建立大最大堆的。

大顶堆,就将上面的第三个参数换成:less<int>(),假如元素是int类型的;
小顶堆,就将上面的第三个参数换成:greater<int>(),假如元素是int类型的

【使用样例】

//heap set map函数的使用 
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int a[n];
	for(int i=0;i<n;i++)
	cin>>a[i];
	
	vector<int> va(a,a+n); 
	cout<<"开始时:"<<endl;
	for(int i=0;i<n;i++)
	cout<<va[i]<<" ";
	cout<<endl; 
	
	make_heap(va.begin(),va.end());//此时默认建立的是大根堆
	cout<<"大根堆:"<<endl;
	for(int i=0;i<n;i++)
	cout<<va[i]<<" ";
	cout<<endl;
	
	/*对int类型,可以在第三个参数传入greater<int>()得到最小堆*/
	make_heap(va.begin(),va.end(),greater<int>());
	cout<<"小根堆:"<<endl;
	for(int i=0;i<n;i++)
	cout<<va[i]<<" ";
	cout<<endl;
	return 0;
}

在这里插入图片描述

2. 在堆中增加元素

push_heap(_First, _Last,_Comp)
要先在底层容器(数组或vector)里加入数据,再调用push_heap()。
实现细节:(1)添加元素到vector的尾部;(2)重新调整堆。
该算法必须是在满足堆序的条件下,添加元素。

如,插入15到当前的大根堆里,vector容器名字为max_heap:

max_heap.push_back(15);
push_heap(max_heap.begin(), max_heap.end());
3. 在堆中删除元素

pop_heap(_First, _Last,_Comp)
实现细节:(1)删除堆顶元素;(2)用尾部元素替代max_heap[0];(3)重新调整堆。

(pop_heap操作实际上是我们把堆顶元素取出来,放到了数组或vector容器的末尾,用原来的末尾元素去替代,然后end迭代器减1,执行siftdown()下溯函数来重新调整堆)
注意算法执行完毕后,最大的元素并没有被取走,而是放于底层容器的末尾。如果要取走,则可以使用底部容器(vector)提供的pop_back()函数。
pop_heap()操作后,再调用max_heap.pop_back(),从底层容器中删掉原堆顶元素

pop_heap(max_heap.begin(), max_heap.end());//取出了堆顶元素(也叫删除堆顶元素),放到了底层容器的末尾,原来末尾的元素替代堆顶,end迭代器减1,重新siftdown了堆
max_heap.pop_back();//从底层容器(数组或vector)中删除了元素

4. 堆排序

sort_heap(_First, _Last,_Comp)
既然每次pop_heap可以获得堆顶的元素(假如是大顶堆,每次都获得最大的元素,取出放到了底层容器的末尾),那么我们持续对整个heap做pop_heap操作,每次讲操作的范围向前缩减一个元素(就是每次end迭代器减1)。最终我们可以获得一个递增的序列。
注意:这个排序是在一个堆上进行的。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yozu_Roo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值