堆的基本操作
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; }