目录
1.堆排序
思考:建堆用向上调整建堆还是向下调整建堆?调堆用向上调整还是向下调整?
1.3总结:升序用大堆,降序用小堆。用向下调整建堆。
2.topK
2.3总结:要前k大,建小堆。要前k小,建大堆。
1.堆排序
1.1分析
思考:建堆用向上调整建堆还是向下调整建堆?调堆用向上调整还是向下调整?
1.2代码参考:
//堆排序
void HeapSort(HPDataType* a, int n) {assert(a);//先建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--) {AdjustDown(a, i, n);}//排序,用up还是down?用小堆还是大堆//用down// 结果要升序,用大堆。结果要降序,用小堆int end = n - 1;while (end > 0) {Swap(&a[0], &a[end]); AdjustDown(a,0, end); --end;}}
int main() {int a[] = { 3,6,1,5,8,9,2,7,4,0 };HeapSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++) {printf("%d ",a[i]);}return 0;
}
1.3总结:升序用大堆,降序用小堆。用向下调整建堆。
2.topK
2.1分析:
2.2 代码参考:
//top k问题
void CreateNDate()
{//造数据int n = 10000;srand((unsigned int)time(NULL));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (int i = 0; i < n; ++i){int x = (rand() + i) % 100000;fprintf(fin, "%d\n", x);}fclose(fin);
}
void topk()
{//获取kprintf("请输入k:");int k = 0;scanf("%d", &k);//先从文件中获取k个数据const char* file = "data.txt";FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen error");return;}int* minheap = (int*)malloc(sizeof(int) * k);if (minheap == NULL) {perror("malloc fail ");return;}for (int i = 0; i < k; i++) {fscanf(fout, "%d", &minheap[i]);}//将k个数据,通过向下调整,建成小堆for (int i = (k - 1 - 1) / 2; i >= 0; i--) {AdjustDown(minheap, i, k);}//遍历文件剩余值(N-k),如果碰见比堆顶大的数据,就入堆int x = 0;while (fscanf(fout, "%d", &x) != EOF){//读取剩余数据,比堆顶的值大,就替换他进堆if (x > minheap[0]) {minheap[0] = x;AdjustDown(minheap, 0, k);} }//将top k打印出来for (int i = 0; i < k; i++) {printf("%d ", minheap[i]);}fclose(fout);
}
int main()
{ CreateNDate();topk();return 0;}