堆的基本操作
Heap.h
#pragma once
//指针可以赋值,类型不可以赋值
typedef int(*Compare)(DataType , DataType );//compare是一个类型
typedef int DataType;
typedef struct Heap
{
DataType* _array;
int _capacity;
int _size;
Compare _compare;
}Heap;
void HeapCreate(Heap *hp, DataType*array, int size, Compare com);
void PrintfHeap(Heap hp);
void InsertHeap(Heap *hp, DataType data);
void DeleteHeapTop(Heap *hp);
int SizeHeap(Heap *hp);
//大堆
int Greater(DataType left, DataType right);
//小堆
int Less(DataType left, DataType right);
Heap.c
#include "Heap.h"
#include<assert.h>
#include<stdlib.h>
#include<malloc.h>
#include<stdio.h>
//小堆
int Less(DataType left, DataType right){
return left < right;
}
//大堆
int Greater(DataType left, DataType right){
return left > right;
}
//交换
void swap(DataType*a,DataType *b){
DataType c = 0;
assert(a);
assert(b);
c = *a;
*a = *b;
*b = c;
}
//调整堆向下
void HeapAdjustDown(Heap* hp, int parent){
//用child来标记左右孩子中最小的元素
int child = parent * 2 + 1;
int size = hp->_size;
while (child<size)
{
if ((child + 1)<size&&(hp->_compare(hp->_array[child+1],hp->_array[child])))
child += 1;
if (hp->_compare(hp->_array[child],hp->_array[parent]))
{
swap(&hp->_array[parent], &hp->_array[child]);
//交换后就影响了下面的结构,需要继续调
parent = child;
child = parent * 2 + 1;
}
else
{
return;
}
}
}
//调整堆向上
void HeapAdjustUp(Heap* hp, int child){
int parent = ((child-1)>>1);
while (child)
{
if (hp->_compare(hp->_array[child],hp->_array[parent]))
{
swap(&hp->_array[parent], &hp->_array[child]);
child = parent;
parent = ((child - 1) >> 1);
}
else
return;
}
}
//堆创建
void HeapCreate(Heap *hp, DataType*array, int size,Compare com){
int i = 0;
int root = ((size - 2) >> 1);
if (hp == NULL)
return;
hp->_array = (DataType*)malloc(sizeof(DataType)*size);
if (hp->_array==NULL)
{
assert(0);
return;
}
//将数组的元素放到堆中去
for (i = 0; i < size; i++)
{
hp->_array[i] = array[i];
}
hp->_size = size;
hp->_capacity = size;
hp->_compare = com;
//堆调整1.向下调整
for (; root >=0; --root)
{
HeapAdjustDown(hp,root);
}
}
//检查堆容量 //开辟新空间,搬移元素,释放旧空间
void _CheckCapacity(Heap *hp){
int i = 0;
assert(hp);
if (hp->_size==hp->_capacity)
{
int NewCapacity = 2 *(hp->_capacity);
DataType *temp = (DataType*)malloc(NewCapacity*sizeof(DataType));
if (temp==NULL)
{
assert(0);
return;
}
for (i = 0; i < hp->_size; i++)
{
temp[i] = hp->_array[i];
}
free(hp->_array);
hp->_array = temp;
}
}
//向堆中插入元素
void InsertHeap(Heap *hp,DataType data){
assert(hp);
_CheckCapacity(hp);
hp->_array[hp->_size++] = data;
int child = (hp->_size) - 1;
HeapAdjustUp(hp, child);
}
void PrintfHeap(Heap hp){
int i = 0;
int size = hp._size;
for (i = 0; i < size; i++)
{
printf("%d ", hp._array[i]);
}
printf("\n");
}
int EmptyHeap(Heap *hp){
assert(hp);
return 0 == hp->_size;
}
//向堆中删除元素--一般删除堆顶元素
void DeleteHeapTop(Heap *hp, DataType data){
assert(hp);
if (EmptyHeap(hp))
return;
hp->_array[0] = hp->_array[hp->_size-1];
hp->_size--;
HeapAdjustDown(hp, 0);
}
//堆中有效的元素
int SizeHeap(Heap *hp){
return hp->_size;
}
堆的应用---优先级队列
PriorityQueue.h
#include "Heap.h"
//优先级队列
typedef struct PriorityQueue
{
Heap _hp;
}PriorityQueue;
//优先级队列基本操作
void PriorityQueueInit(PriorityQueue *q, Compare com);
void PriorityQueuePush(PriorityQueue *q,DataType data);
void PriorityQueuePop(PriorityQueue *q);
void PriorityQueueSize(PriorityQueue *q);
int PriorityQueueEmpty(PriorityQueue *q);
void PriorityQueuePrint(PriorityQueue q);
DataType PriorityQueueTop(PriorityQueue *q);
PriorityQueue.c
#include "Heap.h"
#include "PriorityQueue.h"
void PriorityQueueInit(PriorityQueue *q,Compare com){
HeapInit(&q->_hp,com);
}
void PriorityQueuePush(PriorityQueue *q, DataType data){
InsertHeap(&q->_hp, data);
}
void PriorityQueuePop(PriorityQueue *q){
DeleteHeapTop(&q->_hp);
}
void PriorityQueueSize(PriorityQueue *q){
return SizeHeap(&q->_hp);
}
int PriorityQueueEmpty(PriorityQueue *q){
return EmptyHeap(&q->_hp);
}
void PriorityQueuePrint(PriorityQueue q){
PrintfHeap(q._hp);
}
DataType PriorityQueueTop(PriorityQueue *q){
return GetHeapTop(&q->_hp);
}
堆的应用---堆排序
HeapSort.c
#include "Heap.h"
#include<stdio.h>
#include<stdlib.h>
//向下调整
void HeapAdjust(int *arrar,int size,int parent){
int child = parent * 2 + 1;
while (child<size)
{
if ((child + 1)<size&&arrar[child + 1]>arrar[child])
child += 1;
if (arrar[parent]<arrar[child])
{
swap(&arrar[parent], &arrar[child]);
parent = child;
child = parent * 2 + 1;
}
else
return;
}
}
void HeapSort(int arrar[],int size){
//1,建堆
int root = ((size - 2) >> 1);
int end = size - 1;
for ( ; root>=0; --root)
{
HeapAdjust(arrar, size, root);
}
//2,调整
while (end)
{
swap(&arrar[end],&arrar[0]);
HeapAdjust(arrar, end, 0);
--end;
}
}
int main(){
int arrar[] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 };
int size = sizeof(arrar) / sizeof(arrar[0]);
HeapSort(arrar,size);
for (int i = 0; i <size; i++)
{
printf("%d ", arrar[i]);
}
system("pause");
return 0;
}