Heap.h
#ifndef __HEAP_H__
#define __HEAP_H__
typedef int HPDataType;
typedef struct Heap
{
HPDataType* _hp;
int _capacity;
int _size;
}Heap;
typedef struct PriorityQueue
{
Heap hp;
}PriorityQueue;
void CreatHeap(Heap* hp, int* array, int size);//创建堆
void InitHeap(Heap* hp); // 初始化堆
void PrintHeap(Heap hp);//打印堆
void InsertHeap(Heap* hp, HPDataType data);//插入数据
void RemoveHeap(Heap* hp);//删除堆顶元素
int SizeHeap(Heap*hp);//堆大小
int EmptyHeap(Heap* hp);//判空
HPDataType TopHeap(Heap* hp);//找出堆顶元素
void AdjustDown(Heap* hp, int parent);//向下调整
void AdjustUp(Heap* hp, int child);//向上调整
void _CheakCapacity(Heap* hp);//扩容
void DestroyHeap(Heap* hp); // 销毁堆
int Less(HPDataType left, HPDataType right); // 小于比较
int Greater(HPDataType left, HPDataType right); // 大于比较
void InitPriorityQueue(PriorityQueue* q);
void PushPriorityQueue(PriorityQueue* q, HPDataType data);
void PopPriorityQueue(PriorityQueue* q);
int TopPriorityQueue(PriorityQueue* q);
int SizePriorityQueue(PriorityQueue* q);
int EmptyPriorityQueue(PriorityQueue* q);
void Topk(Heap* q, int k);//海量数据中的topk问题
void HeapSort(Heap *q);//堆排序
Heap.c
#include "Heap.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
void CreatHeap(Heap* hp, int* array, int size)
{
int i = 0;
int root = (size-2)/2;
assert(hp);
hp->_hp = (HPDataType*)malloc(sizeof(HPDataType)*size);
if(NULL == hp->_hp)
{
assert(hp);
return;
}
hp->_capacity = size;
hp->_size = size;
for(i=0;i<size;i++)
{
hp->_hp[i] = array[i];
}
for(i=root;i>=0;i--)
{
AdjustDown(hp,i);
}
}
void InitHeap(Heap* hp)
{
assert(hp);
hp->_hp = (HPDataType*)malloc(sizeof(HPDataType));
if(NULL == hp->_hp)
{
return;
}
hp->_capacity = 1;
hp->_size = 0;
}
void PrintHeap(Heap hp)
{
int i = 0;
for(i=0;i< hp._size;i++)
{
printf("%d ", hp._hp[i]);
}
}
void Swap(int* left,int* right)
{
int temp = 0;
temp = *left;
*left = *right;
*right = temp;
}
int Greater(HPDataType left, HPDataType right)
{
if (left > right)
return 1;
return 0;
}
int Less(HPDataType left, HPDataType right)
{
if (left < right)
return 1;
return 0;
}
void AdjustDown(Heap* hp, int parent)
{
int child = 2*parent+1;
assert(hp);
while(child < hp->_size)
{
if(Greater(hp->_hp[child],hp->_hp[child+1]) && (child+1) < hp->_size)
{
child = child+1;
}
if(Greater(hp->_hp[parent] , hp->_hp[child]))
{
Swap(&hp->_hp[parent],&hp->_hp[child]);
parent = child;
child = 2*parent+1;
}
else
return;
}
}
void AdjustUp(Heap* hp, int child)
{
int parent = (child-1)/2;
assert(hp);
while(child != 0)
{
if(Greater(hp->_hp[parent],hp->_hp[child]))
{
Swap(&hp->_hp[parent],&hp->_hp[child]);
child = parent;
parent = (child-1)/2;
}
else
return;
}
}
void _CheakCapacity(Heap* hp)
{
int i = 0;
assert(hp);
if(hp->_capacity == hp->_size)
{
hp->_hp = (HPDataType*)realloc(hp->_hp,sizeof(HPDataType)*(hp->_capacity)*2);
if(NULL == hp->_hp)
{
return;
}
hp->_capacity = 2*hp->_capacity;
}
}
void InsertHeap(Heap* hp, HPDataType data)
{
int i = 0;
assert(hp);
_CheakCapacity(hp);
hp->_hp[hp->_size++] = data;
AdjustUp(hp,hp->_size-1);
}
int EmptyHeap(Heap* hp)
{
assert(hp);
if (hp->_size == 0)
return 1;
return 0;
}
void RemoveHeap(Heap* hp)
{
assert(hp);
//判断堆是否为空
if (EmptyHeap(hp))
return;
//先将堆顶元素和堆尾元素交换,并删除堆尾元素
Swap(&(hp->_hp[0]), &hp->_hp[hp->_size - 1]);
hp->_size--;
//用向下调整法调整队列
AdjustDown(hp, 0);
}
int SizeHeap(Heap*hp)
{
assert(hp);
return hp->_size;
}
HPDataType TopHeap(Heap* hp)
{
assert(hp);
if (hp->_size == 0)
{
return 0;
}
return hp->_hp[0];
}
void DestroyHeap(Heap* hp)
{
assert(hp);
hp->_size = 0;
hp->_capacity = 0;
free(hp->_hp);
hp->_hp = NULL;
return;
}
///优先级队列
void InitPriorityQueue(PriorityQueue* q)
{
InitHeap(&q->hp);
}
void PushPriorityQueue(PriorityQueue* q, HPDataType data)
{
InsertHeap(&q->hp, data);
}
void PopPriorityQueue(PriorityQueue* q)
{
int i = 0;
int root = (q->hp._size-2)/2;
RemoveHeap(&q->hp);
for(i=root;i>=0;i--)
{
AdjustDown(&q->hp,i);
}
}
int TopPriorityQueue(PriorityQueue* q)
{
return TopHeap(&q->hp);
}
int SizePriorityQueue(PriorityQueue* q)
{
return SizeHeap(&q->hp);
}
int EmptyPriorityQueue(PriorityQueue* q)
{
return EmptyHeap(&q->hp);
}
//topk问题
void Topk(Heap* q, int k)
{
int i = 0;
int j = 0;
assert(q);
q->_hp = (HPDataType*)malloc(sizeof(HPDataType)*k);
if(q->_hp == NULL)
{
assert(0);
return;
}
//首先取前K个数,用着K个数来创建一个小堆
for(i=0;i<k;i++)
{
int temp = rand()%10000;
q->_hp[i] = temp;
}
q->_size = k;
for(i=(k-2)/2;i>=0;i--)
{
AdjustDown(q,i);
}
//然后,一个一个的取数组内剩下的数,取出的数与堆顶的元素比较,如果比堆顶的元素大的话,就用取出的元素
//代替堆顶的元素,代替之后再进行向下的调整,使堆重新满足小堆的特性,然后再从数组内取数据,重复上述操作,直到所有的数组为空时
for(j=k;j<10000;j++)
{
int temp = rand()%10000;
if(temp > q->_hp[0])
{
Swap(&temp,&q->_hp[0]);
AdjustDown(q,0);
}
}
PrintHeap(*q);
}
//堆排序
//如果是降序的话, 建一个小堆
//然后,先将小堆的堆顶的值与堆底的值交换,这样最小值就到了堆底,然后调整的元素个数-1,向下法调整交换后的堆
//调整好的堆最小值又在堆顶,然后再次与最后的元素交换,直到元素个数为0时停止
void HeapSort(Heap *q)
{
int i = q->_size;
assert(q);
i = q->_size;
while(i)
{
//交换堆底和堆顶的元素
Swap(&q->_hp[i-1], &q->_hp[0]);
//把最小值放到堆底之后,元素个数-1;
--i;
//调整剩下的几个元素的堆
AdjustDown(q,0);
}
}