#include"Heap.h"voidSwap(HPDataType* px, HPDataType* py){// 交换函数
HPDataType tmp =*px;*px =*py;*py = tmp;}voidHeapInit(HP* hp){// 初始化堆assert(hp);
hp->a =NULL;
hp->size =0;
hp->capacity =0;}voidHeapDestory(HP* hp){assert(hp);free(hp->a);
hp->size =0;
hp->capacity =0;}voidAdjustUp(HPDataType* a,int child){//向上调整assert(a);int parent =(child -1)/2;while(child >0){if(a[child]< a[parent]){Swap(&a[child],&a[parent]);
child = parent;
parent =(child -1)/2;}else{break;}}}voidHeapPrint(HP* hp){for(int i =0; i < hp->size; i++){printf("%d ", hp->a[i]);}printf("\n");}voidHeapPush(HP* hp, HPDataType x){assert(hp);if(hp->capacity == hp->size){//考虑扩容int newCapacity = hp->capacity ==0?4:2*(hp->capacity);
HPDataType* tmp =realloc(hp->a,sizeof(HPDataType)*newCapacity);if(tmp ==NULL){printf("realloc fail\n");exit(-1);}
hp->a = tmp;
hp->capacity = newCapacity;}
hp->size++;
hp->a[hp->size]= x;AdjustUp(hp->a, hp->size -1);}
bool HeapEmpty(HP* hp){assert(hp);return hp->size ==0;}intHeapSize(HP* hp){assert(hp);return hp->size;}
HPDataType HeapTop(HP* hp){//读取堆顶元素assert(hp);assert(!HeapEmpty(hp));return hp->a[0];}voidAdjustDown(HPDataType* a,int n,int parent){int child = parent *2+1;//得到的是左子树的结点while(child < n){if(child +1< n && a[child +1]< a[child]){//当右节点小时,选择小的结点向下调整
child++;}//如果孩子结点小于父亲结点时,需要调整if(a[child]< a[parent]){Swap(&a[child],&a[parent]);
parent = child;
child = parent *2+1;}else{break;}}}//删除栈顶元素,删除栈顶元素时,栈顶元素和最后一个元素的位置交换,然后向下调整voidHeapPop(HP* hp){assert(hp);assert(!HeapEmpty(hp));Swap(&hp->a[0],&hp->a[hp->size -1]);
hp->size--;AdjustDown(hp->a, hp->size,0);}voidHeapSort(HPDataType* a,int n){for(int i =(n -1-1)/2; i >=0; i--){AdjustDown(a, n, i);}for(int end = n -1; end >0; end--){Swap(&a[end],&a[0]);AdjustDown(a, end,0);}}voidPrintTopK(HPDataType* a,int n,int k){
HP hp;HeapInit(&hp);// 创建一个K个数的小堆for(int i =0; i < k;++i){HeapPush(&hp, a[i]);}// 剩下的N-K个数跟堆顶的数据比较,比他大,就替换他进堆for(int i = k; i < n;++i){if(a[i]>HeapTop(&hp)){HeapPop(&hp);HeapPush(&hp, a[i]);//hp.a[0] = a[i];//AdjustDown(hp.a, hp.size, 0);}}HeapPrint(&hp);HeapDestroy(&hp);}voidTestTopk(){int n =1000000;int* a =(int*)malloc(sizeof(int)*n);srand(time(0));for(size_t i =0; i < n;++i){
a[i]=rand()%1000000;}// 再去设置10个比100w大的数
a[5]=1000000+1;
a[1231]=1000000+2;
a[5355]=1000000+3;
a[51]=1000000+4;
a[15]=1000000+5;
a[2335]=1000000+6;
a[9999]=1000000+7;
a[76]=1000000+8;
a[423]=1000000+9;
a[3144]=1000000+10;PrintTopK(a, n,10);}
main.c的相关内容:
#include"Heap.h"intmain(){int a[]={70,56,30,25,15,10,75,33,50,69};
HP hp;HeapInit(&hp);for(int i =0; i <sizeof(a)/sizeof(a[0]); i++){printf("%d ", a[i]);}printf("\n");HeapSort(a,sizeof(a)/sizeof(a[0]));for(int i =0; i <sizeof(a)/sizeof(a[0]); i++){printf("%d ", a[i]);}printf("\n");return0;}