堆这种数据结构呢,就是一种能保证堆顶元素是最大元素,或最小元素的一种数据结构,维护时间为log2 N
下面介绍我们就拿最大堆来说,不失一般性
首先说堆的结构:堆的结构就一个要求,根节点大于他的两个子节点
首先说元素的删除,我们只能删除堆顶元素
我们删除堆顶元素后将堆尾元素heap【top】与堆顶元素heap【1】交换 此时堆的长度top=top-1;
然后找到他的子节点中较大的那个 :t
如果此元素大于子节点中较大的那个,就交换 并且继续往下找,直到一直找到堆尾
否则,维护完成,退出维护
int k=1;
heap[k]=heap[top--];//将堆尾元素移到堆首
while (k*2<=top)
{
int t=k*2;
if (t<top&&compare(heap[t+1]),heap[t]<0)
t++;//t为结点k左右结点中较小的那个
if (compare(heap[k],heap[t])<0)
{Swap(heap[t],heap[k]);k=t;}
else break;
}
再说元素的进入
我们将新读入的元素放在堆尾
然后一个一个往上维护
while (k>1)
{
int t=k/2;
if (compare(heap[t],heap[k])>0)
{Swap(heap[t],heap[k]);k=t;}
else break;
}
对于结构体来说就要写自己的compare了
下面是一个结构体的例子
题目为 zoj2724
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=60010;
const int maxs=100;
struct info
{
char name[maxs];
int para,pri,t;
}p[maxn];
int compare(int a,int b)
{
if (p[a].pri<p[b].pri)
return -1;
if (p[a].pri>p[b].pri)
return 1;
if (p[a].t<p[b].t)
return -1;
if (p[a].t>p[b].t)
return 1;
return 0;
}
void Swap(int&a,int&b)
{
int c;
c=a;a=b;b=c;
return;
}
int heap[maxn];
int top,used;
int main()
{
used=0;
top=0;
int cnt=0;
while (scanf("s",s)!=EOF)
{
if (!strcmp(s,"GET"))
{
if (top)
{
printf("%s %d",p[heap[1]].name,p[heap[1]].para);//输出堆顶元素
int k=1;
heap[k]=heap[top--];//将堆尾元素移到堆首
while (k*2<=top)
{
int t=k*2;
if (t<top&&compare(heap[t+1]),heap[t]<0)
t++;//t为结点k左右结点中较小的那个
if (compare(heap[k],heap[t])<0)
{Swap(heap[t],heap[k]);k=t;}
else break;
}
}
else printf("EMPTY QUEUE!\n");
}
else
{
scanf("%s%d%d",p[used].name,&p[used].para,&p[used].pri);//将used作为缓冲区
p[used].t=cnt++;
int k=++top;
heap[k]=used++;
while (k>1)
{
int t=k/2;
if (compare(heap[t],heap[k])>0)
{Swap(heap[t],heap[k]);k=t;}
else break;
}
}
}
return 0;
}
//堆这种数据结构就是能保证第一个是最大值或者最小值并且边输入遍维护的