关于STL中堆的建立

最近总有新手要问堆怎么写,我是这么想的

既然都学c++了,堆这种东西怎么能手写呢,太对不起STL了

(当然能手写的都是的大神了,这只是我懒得手打的理由)

正好之前机房有位大神将他学习的堆教给了我

我就以他讲的写一篇blog来帮助其他人吧

这里先介绍一下vector

vector是一个动态数组

当你需要多少空间时就会自动分配多少空间给你

极大的省了许多空间(通常我是拿来存图的),声明方法如下

先加头文件 #include
声明: vector<参数> 变量名 然后要什么类型就在参数里写什么类型
这里我们只需要用int就行

因为我们只需要存数字,存图时通常用结构体,详细用法自行看百度吧,

vector a

这样我们就有一个可以存放数字的动态数组a了,

接着学习几个基本操作

加入数据 : a.push_back(num)
删除最后一个数据 : a.pop_back()
队尾+1的位置 : a.end() 注意:a.end()是一个迭代器,我也不知道是什么,反正只要减去数组的名字就可以得到末尾往后的位置的下标
队首的位置 : a.begin() 这也是一个迭代器
然后就是开始了

用for循环读入数据

1
2
3
4
5
6
for(int i=1;i<=n;i++)
{
  int num;
   scanf(“%d”,&num);
   a.push_back(num);
}
然后开始建堆

用algorithm中的三个函数就可以搞定了

先加#include

里面有一个函数为make_heap()

现在我们要把a数组变为一个堆,就这么写

1
make_heap(a.begin(),a.end(),cmp)
注意,cmp是自己添加的一个函数,返回值应该是bool

而这里的cmp很特殊

小根堆的cmp是这么写的

1
2
3
4
bool cmp(int x,int y)
{
return x>y;
}
注意,我并没有写错,就是大于号,所以才说它特殊

往后如果再推入元素需要进行维护

如果建堆的时候写了cmp这个参数,那每次都要再传入一遍

再推入的时候是这样的

先加入a数组里

a.push_back(num)

再用一个函数维护一下

push_heap(a.begin(),b.end(),cmp)

此时,a这个动态数组又变成堆了

而堆我们通常是取第一个元素,而vector的第一个元素和数组一样

直接取a[0]即可

取完a[0]以后,你可能要删掉这个堆顶的元素

删除刚好和加入相反

同样有一个函数是用来删除堆的元素的

pop_heap(a.begin(),a.end(),cmp)

注意这里还没完,它的功能只是将第一个元素放到最后,然后忽略最后一个元素的情况下再维护一遍堆

所以我们还得用a.pop_back()把最后一个元素推掉

这样堆的建立插入和删除操作就讲完了

  #include<cstdio>
  #include<iostream>
  #include<algorithm>
  #include<vector>
  bool cmp(int x,int y)
  {
      return x>y;
  }
  int main()
 {
     vector<int> a;
     int num,n;
     scanf("%d",&n);
     for(int i=1;i<=n;i++)
     {
         scanf("%d",&num);
         a.push_back(num);
     }
     make_heap(a.begin(),a.end(),cmp);
     scanf("%d",&num);
     a.push_back(num);
       push_heap(a.begin(),a.end(),cmp);
       cout<<a[0]<<endl;
     pop_heap(a.begin(),a.end(),cmp);
     a.pop_back();
     return 0;
 }

也可以用priority_queue来建;
大根堆:priority_queue heap
小根堆:priority_queue

猜你喜欢

转载自blog.csdn.net/doge__/article/details/81623624