堆是一个优先队列;取出元素的顺序是依照优先值大小;
堆是一个用数组存储的完全二叉树,任何一个节点是其子树的所有节点的最大值(最小值);
堆的结构
typedef struct Node* Heap;
#define MAXDATA 1000
struct Node
{
int* data; // 存储堆的数据
int size; // 当前数组的大小
int Maxsize; //数组容量的大小
}
建立一个堆
MaxHeap createMaxHeap(int Max)
{
MaxHeap H = (MaxHeap)malloc(sizeof(struct HNode));
H->data = (int*)malloc((Max+1) * sizeof(int));
H->data[0] = MAXDATA; //把第一个节点的值设为最大的值
H->Maxsize= Max;
H->size = 0;
return H;
}
判断堆是否为空
bool IsEmpty(Heap H)
{
if(H->size == 0)
{
return true;
}
return false;
}
判断堆是否满
bool IsFull(Heap H)
{
if(H->size == H->Maxsize)
return true;
return false;
}
向堆中插入元素
void InsertHeap(Heap H , int item)
{
if(Isfull(H))
{
printf("堆已满\n");
return;
}
int i ;
i = ++H->size; //更新size
for(;H->data[i/2]<item;i/=2) //向上比较,寻找插入位置
{
H->data[i] = H->data[i/2];
}
H->data[i] = item; //插入元素
}
从堆中取出一个元素
int DeleteMaxHeap(Heap H)
{
int Parent, Child, Tmp;
int Maxitem;
if (IsEmpty(H))
{
printf("堆为空");
return -1;
}
Maxitem = H->data[1]; //取出最大元素
Tmp = H->data[H->size--]; //取出最后一个元素
// 把最后一个元素向下比较,寻找插入位置
for (Parent = 1; Parent * 2 <= H->size; Parent = Child)
{
Child = Parent * 2;
if ((Child != H->size)&& H->data[Child +1]>H->data[Child])
{
Child++;
}
if (Tmp >= H->data[Child])
{
break;
}
else
{
H->data[Parent] = H->data[Child];
}
}
H->data[Parent] = Tmp; // 把最后一个元素放在合适的位置
return Maxitem;
}
堆的建造
void PercDown(Heap H, int p)
{
if (IsEmpty(H))
{
printf("堆为空");
return;
}
int Parent, Child, Tmp;
Tmp = H->data[p];
for (Parent = 1; Parent * 2 <= H->size; Parent = Child)
{
Child = Parent * 2;
if ((Child != H->size)&& H->data[Child +1] > H->data[Child])
{
Child++;
}
if (Tmp < H->data[Child])
{
H->data[Parent] = H->data[Child];
}
else
{
break;
}
}
H->data[Parent] = Tmp;
}
void BuildHeap(Heap H)
{
/* 调整H->Data[]中的元素,使满足最大堆的有序性 */
/* 这里假设所有H->Size个元素已经存在H->Data[]中 */
int i;
/* 从最后一个结点的父节点开始,到根结点1 */
for (i = H->size / 2; i > 0; i--)
PercDown(H, i);
}