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; }