堆的插入:
这里以最大堆为例子,先将要插入的元素放在堆的末尾,然后将其与父节点比较,如果比父节点大,那么就与父节点交换。
重复此操作,这里有个技巧,可以在堆的上面设一个很大的元素,称为哨兵,这样即使是到了堆顶也会自动停下。不会出现超范围的问题。
堆的删除:
堆的删除指的是删除堆的最大元素,也就是堆顶。删除完之后将堆尾的元素拿到堆首,然后再与两个孩子中的较大的元素进行比较,如果小,则交换,重复此步骤,直到比它们都大或者没有孩子的时候。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1005;
struct heap //最大堆
{
int data[maxn];
int Size;
};
heap h;
int n;
void init() //初始化
{
h.Size=0;
h.data[0]=INF; //哨兵
}
void Insert(int data) //插入
{
h.data[++h.Size]=data;
int i=h.Size;
while (data>h.data[i/2])
{
h.data[i]=h.data[i/2];
i/=2;
}
h.data[i]=data;
}
bool IsEmpty() //判断是否为空
{
if(h.Size==0)
return true;
else
return false;
}
int DeleteMax () //删除栈顶元素
{
if(IsEmpty())
return -1;
int parent,child;
int temp=h.data[1];
int data=h.data[h.Size--];
for (parent=1;parent*2<=h.Size;parent=child)
{
child=parent*2;
if((child!=h.Size)&&h.data[child]<h.data[child+1])
child+=1;
if(h.data[child]>data)
h.data[parent]=h.data[child];
else
break;
}
h.data[parent]=data;
return temp;
}
int main()
{
scanf("%d",&n);
init();
for (int i=0;i<n;i++)
{
int m;
scanf("%d",&m);
Insert(m);
}
while (DeleteMax()!=-1)
{
for (int i=1;i<=h.Size;i++)
printf("%d ",h.data[i]);
printf("\n");
}
return 0;
}