代码主要借鉴《Data Structures and Algorithm Analysis in C (Second Edition)》。
插入操作就是现在最底部创建一个空穴,然后上滤。
删除操作用下滤实现,注意要考虑一个节点只有一个儿子的情况(这种情况只可能出现在堆的最后)。
逐层输出利用stl的queue实现,实现的过程类似bfs。
/* something about heap */
#include <cstdio>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef struct heaap{
int ele[5000];
int level[5000];
int size;
int max;
}hea;
typedef hea* heap;
heap initial()
{
heap newheap;
newheap = (heap) malloc (sizeof(hea));
newheap->size = 0;
return newheap;
}
void insert(int key, heap target)
{
int i;
if(target->size == 0)
{
target->size++;
target->ele[target->size] = key;
target->level[target->size] = 1;
return ;
}
for(i = ++target->size; target->ele[i/2] > key; i /= 2)
target->ele[i] = target->ele[i/2];
target->level[target->size] = log(target->size)/log(2) + 1; //每插入一个元素,就会在堆的最下方产生一个新的穴,为了逐层输出,我们需要确定它在第几层。因为二叉堆是完全二叉树,多以第n个节点在第[log(n)/log(2)+1向下取整]层上。
//printf("level = %d\n",target->level[target->size]);
target->ele[i] = key;
return ;
}
void print(heap tar)
{
if(tar->size == -1)
{
printf("BLANK HEAP\n");
return ;
}
else
{
queue<int> que;
que.push(1);
int level = tar->level[1];
while(!que.empty())
{
int temp = que.front();
que.pop();
if(level != tar->level[temp])
{
printf("\n");
level = tar->level[temp];
}
printf("%d ",tar->ele[temp]);
if(temp * 2 <= tar->size)
que.push(temp * 2);
if(temp * 2 + 1 <= tar->size)
que.push(temp * 2 + 1);
}
}
printf("\n\n");
}
int topandpop(heap tar)
{
int i, child;
int minele, lastele;
if(tar->size == 0)
{
printf("PriorityQueue is Empty\n");
return 0;
}
minele = tar->ele[1];
lastele = tar->ele[tar->size--];
for(i = 1; i*2 <= tar->size; i = child)
{
child = i*2;
if(child != tar->size && tar->ele[child+1] < tar->ele[child])
child++;
if(lastele > tar->ele[child])
tar->ele[i] = tar->ele[child];
else
break;
}
tar->ele[i] = lastele;
return minele;
}
int main()
{
//freopen("ztest.txt","r",stdin);
printf("Call For a PriorityQueue\n");
heap newheap = initial();
int n;
while(scanf("%d", &n) && n)
insert(n, newheap);
printf("\n\n");
print(newheap);
printf("1 is delete minimum and pop it while 0 is quit\n");
while(scanf("%d", &n) && n)
{
printf("\n\ntop : %d\n\n",topandpop(newheap));
print(newheap);
}
return 0;
}