堆是一种特殊的完全二叉树。以小根堆为例,这种完全二叉树有一个特点,就是它的父节点都比子节点小。符合这样特点的二叉树,我们也称为最小堆。
反之,如果所有父节点都比子节点要大,这样的完全二叉树称为大根堆,或最大堆。
(若是最小堆,则最小的数在堆顶/树根。)
按一般意义来讲,一个堆的父节点的优先级都比子节点高。
堆有两种基本的写法
1.手写堆
```cpp
#include
#include
#include
#include
#define leftson (cur<<1)
#define rightson (cur<<1|1)
#define father (cur>>1)
#define int long long
#define MAXN 1000000+10
int n=0,m;
int heap[MAXN];
namespace self
{
#define int long long
void swap(int h[],int x,int y)
{
int t; t=h[x]; h[x]=h[y]; h[y]=t;
return;
}
using namespace self;
void siftdown(int h[],int i)
{
int t;
bool flag=0;
while (i*2<=n && flag==0)
{
if (h[i]>h[i*2])
t=i*2;
else t=i;
if (i*2+1<=n)
{
if(h[t]>h[i*2+1])
t=i*2+1;
}
if (t!=i)
{
swap(heap,t,i);
i=t;
}
else flag=1;
}
return;
}
}
using namespace self;
void down(int cur)
{
int t;
bool flag=0;
while (leftson<=n&&(!flag))
{
if (heap[cur]>heap[leftson])
{
t=leftson;
}
else t=cur;
if (rightson<=n)
{
if (heap[t]
2.STL 堆:优先队列
队列是一种先进先出(FIFO)式的数据结构。优先队列与其不同的地方是,优先队列存储的时候,会将(定义的)优先级较大的元素放在较小的元素之前。也就是说优先级最大的元素放在队头。 那么这里就和堆有了共同点:优先级大的放在队前/堆高层。
大根堆的定义:
queue< int >q;
小根堆的定义:
priority_queue< int,vector< int >,greater< int > >q;
一个优先队列的操作:
![qwq](https://img2018.cnblogs.com/blog/1502584/201903/1502584-20190315131434620-2042581491.png)
### 小根堆基本操作代码
```cpp
#include
#include
#include
#include
#include
using namespace std;
priority_queue,greater >q;
int main()
{
int n;
scanf("%d",&n);
int x;
while(n--)
{
scanf("%d",&x);
if (x==1)//命令1 在堆中加入一个数
{
scanf("%d",&x);
q.push(x);
continue;
}
if (x==2)//命令2 输出当前序列中最小数
{
printf("%d
",q.top());
continue;
}
if (x==3)//命令3 删除当前序列中最小数
q.pop();
}
return 0;
}
```