Heap.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>
#include <string.h>
typedef int DataType;
typedef int (*Compare)(DataType left,DataType right);//函数指针
typedef struct Heap
{
DataType* _array;//数组指针
int _capacity;//数组容量
int _size;//元素个数
Compare _com;
}Heap;
//交换函数
void Swap(DataType *left,DataType *right);
//向下调整
void AdjustDown(Heap* hp,int parent);
//向上调整
void AdjustUp(Heap* hp,int child);
//创建堆
void Create(Heap* hp,DataType* array,int size,Compare com);
//初始化堆
void HeapInit(Heap* hp,Compare com);
//堆中插入元素
void HeapInsert(Heap* hp,DataType data);
//判空
int HeapEmpty(Heap* hp);
//销毁堆
void DestoryHeap(Heap* hp);
//扩容
void CheckCapacity(Heap* hp);
//堆的元素个数
int HeapSize(Heap* hp);
//获取堆顶元素
DataType HeapTop(Heap* hp);
//小堆规则
int Less(DataType left,DataType right);
//大堆规则
int Greater(DataType left,DataType right);
//堆排序
void HeapSort(int* array,int size);
void AdjustHeap(int* array,int size,int parent);
void SwapSort(int* left,int* right);
void HeapSortPrint(int* array,int size);
Heap.c
#include "Heap.h"
//交换函数
void Swap(DataType *left,DataType *right)
{
DataType tmp;
tmp = *left;
*left = *right;
*right = tmp;
}
//向下调整
void AdjustDown(Heap* hp,int parent)
{
int child = parent*2+1;
assert(hp);
//默认情况选孩子为左孩子
while(child < hp->_size)
{
//如果右孩子存在且右孩子小于左孩子,那么此时就需要重新标记child为右孩子
if((child+1) < hp->_size && hp->_array[child] > hp->_array[child+1])
child += 1;
if(hp->_array[parent] > hp->_array[child])
{
Swap(&hp->_array[child],& hp->_array[parent]);
parent = child;
child = parent*2+1;
}
else
return;
}
}
//向上调整
void AdjustUp(Heap* hp,int child)
{
int parent = (child-1)>>1;
if(NULL == hp)
return;
if(hp->_array[child] < hp->_array[parent])
{
Swap(&hp->_array[child],&hp->_array[parent]);
child = parent;
parent = (child -1)>>1;
}
else
return;
}
//创建堆
void Create(Heap* hp,DataType* array,int size,Compare com)
{
int i = 0;
int root = 0;
assert(hp);
//1.申请空间
hp->_array = (DataType*)malloc(sizeof(DataType)*size+3);
hp->_capacity = size+3;
//2.放置元素
for( ; i< size;i++)
{
hp->_array[i] = array[i];
hp->_size++;
}
hp->_size = size;
hp->_com = com;
//3.调整,找叶子节点
root = (size-2) >> 1;
for( ; root>=0;root--)
AdjustDown(hp,root);
}
//初始化堆
void HeapInit(Heap* hp,Compare com)
{
assert(hp);
//假设现默认其初始空间申请为3个
hp->_array = (DataType*)malloc(sizeof(DataType)*3);
if(NULL == hp)
{
printf("申请空间失败!!!\n");
return;
}
hp->_capacity = 3;
hp->_size = 0;
hp->_com = com;
}
//堆中插入元素(进行向上调整)
void HeapInsert(Heap* hp,DataType data)
{
assert(hp);
CheckCapacity(hp);
hp->_array[hp->_size++] = data;
if(hp->_size > 1)
AdjustUp(hp,hp->_size-1);
}
//判空
int HeapEmpty(Heap* hp)
{
assert(hp);
return 0 == hp->_size;
}
//删除堆,每次删除删除堆顶元素
void DestoryHeap(Heap* hp)
{
assert(hp);
if(HeapEmpty(hp))
return;
//1.将堆中最后一个元素替代堆顶元素
Swap(&hp->_array[0],&hp->_array[hp->_size-1]);
//2.将堆中元素个数减少一个,即删除堆中最后一个元素
hp->_size--;
//3.堆中结构可能被破坏,再向下调整使其满足对的性质
AdjustDown(hp,0);
}
//扩容
void CheckCapacity(Heap* hp)
{
//realloc做的三件事情
//1.申请新空间
//2.将旧空间的元素搬移到新空间
//3.释放旧空间
if(hp->_size = hp->_capacity)
{
int pNewCapacity = (hp->_capacity)*2;
DataType* newarray = (DataType*)realloc(hp->_array,sizeof(DataType)*pNewCapacity);
if(NULL == newarray)
{
printf("扩容失败!!!\n");
return;
}
free(hp->_array);
hp->_array = newarray;
hp->_capacity = pNewCapacity;
}
}
//堆的元素个数
int HeapSize(Heap* hp)
{
return hp->_size;
}
//获取堆顶元素
DataType HeapTop(Heap* hp)
{
assert(hp);
if(HeapEmpty(hp))
return -1;
return hp->_array[0];
}
//小堆规则
int Less(DataType left,DataType right)
{
return left < right;
}
//大堆规则
int Greater(DataType left,DataType right)
{
return left > right;
}
//堆排序(此处选择降序排序,用小堆)
void HeapSort(int* array,int size)
{
//1.向下调整,将树变为小堆
int root = (size-2)>>2;//找到叶子结点的根
int end = size-1;//找到最后一个叶子结点
while(root>=0)
{
AdjustHeap(array,size,root);//将树调整为小堆,找到的堆顶元素是最小的
root--;
}
while(end > 0)
{
SwapSort(&array[0],&array[end]);//将堆顶元素和最后一个结点的元素交换
AdjustHeap(array,end,0);//若交换后不满足小堆结构就进行堆调整
end--;//记得每次调整都要减去1,调整的时候不需要在计入已排序的元素个数
}
}
void AdjustHeap(int* array,int size,int parent)
{
int child = parent*2+1;
while(child < size)
{
if( (child+1)<size && array[child] > array[child+1] )
child += 1;
if( array[child] < array[parent] )
{
SwapSort(&array[child],&array[parent]);
child = parent;
parent = (child-1)>>1;
}
else
return;
}
}
void SwapSort(int* left,int* right)
{
int tmp;
tmp = *left;
*left = *right;
*right = tmp;
}
void HeapSortPrint(int* array,int size)
{
int i = 0;
for( ; i<size;i++)
{
printf("%d ",array[i]);
}
printf("\n");
}
test.c
#include "Heap.h"
#if 0
int main()
{
Heap hp;
int arr[] = {53,17,78,9,45,65,87,23,31};
HeapInit(&hp,Less);
Create(&hp,arr,sizeof(arr)/sizeof(arr[0]),Less);
printf("top is:%d\n",HeapTop(&hp));
printf("size is:%d\n",HeapSize(&hp));
DestoryHeap(&hp);
printf("top is:%d\n",HeapTop(&hp));
printf("size is:%d\n",HeapSize(&hp));
printf("heap is empty:%d\n",HeapEmpty(&hp));
return 0;
}
#endif
int main()
{
int arr[] = {53,17,78,9,45,65,87,23,31};
int size = sizeof(arr)/sizeof(arr[0]);
HeapSortPrint(arr,size);
HeapSort(arr,size);
HeapSortPrint(arr,size);
return 0;
}