赞
踩
C语言数据结构堆排序、向上调整和向下调整的时间复杂度的计算、TopK问题等的介绍
排列一个一维数组,可以通过两个步骤进行排序。
需要注意的是 堆排序排升序则建大堆,排降序则建小堆。
这里建堆采用向下调整建堆,因为向上调整建堆的时间复杂度比向下调整建堆的时间复杂度大。可参考二。
// 向下调整 按大根堆调整 void AdjustDown(HPDataType* a, int n ,int parent) { int child = parent * 2 + 1; while (child < n) { // 判断左右子树的根谁大 并防止越界 if (child+ 1 < n && a[child] < a[child + 1]) { child++; } if (a[child] > a[parent]) { Swap(&a[parent], &a[child]); parent = child; child = parent * 2 + 1; } else { break; } } } // 排升序 建大堆 void HeapSort(int* arr, int n) { int i = 0; // 建堆---向下调整建堆 for (i = (n - 1 - 1) / 2; i >= 0; i--) { AdjustDown(arr, n, i); } }
// 排升序 建大堆 void HeapSort(int* arr, int n) { int i = 0; // 建堆---向下调整建堆 for (i = (n - 1 - 1) / 2; i >= 0; i--) { AdjustDown(arr, n, i); } // 排序 int end = n - 1; while (end > 0) { Swap(&arr[0], &arr[end]); AdjustDown(arr, end, 0); end--; } } int main() { int arr[10] = { 2,3,1,9,5,7,8,6,4, 0 }; HeapSort(arr, 10); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; }
效果如下:
// 向下调整 按小根堆调整 void AdjustDown(HPDataType* a, int n ,int parent) { int child = parent * 2 + 1; while (child < n) { // 判断左右子树的根谁小 并防止越界 if (child+ 1 < n && a[child] > a[child + 1]) { child++; } if (a[child] < a[parent]) { Swap(&a[parent], &a[child]); parent = child; child = parent * 2 + 1; } else { break; } } } // 拍降序,建小堆 void HeapSort(int* arr, int n) { int i = 0; for (i = (n - 1 - 1) / 2; i >= 0; i--) { AdjustDown(arr, n, i); } }
// 拍降序,建小堆 void HeapSort(int* arr, int n) { int i = 0; // 建堆---- 向下调整建堆 for (i = (n - 1 - 1) / 2; i >= 0; i--) { AdjustDown(arr, n, i); } // 排序 int end = n - 1; while (end > 0) { Swap(&arr[0], &arr[end]); AdjustDown(arr, end, 0); end--; } } int main() { int arr[10] = { 2,3,1,9,5,7,8,6,4, 0 }; HeapSort(arr, 10); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; }
效果如下:
注意拍升序和拍降序的向下调整函数是不一样的
注意: 堆是完全二叉树,这里用满二叉树来近似计算,因为时间复杂度计算的是量级,多或少节点不影响。
见图示:
1.
见图示:
1.
在非常大的数字中找到前K个
void PrintfTopK(const char* file, int k) { int* topk = (int*)malloc(sizeof(int)* k); if (topk == NULL) { perror("PrintfTopK malloc"); return; } // 以读的形式打开文件 FILE* pfout = fopen(file, "r"); if (pfout == NULL) { perror("PrintfTopK fopen"); return; } int i = 0; // 读出前K个数 for (i = 0; i < k; i++) { fscanf(pfout, "%d", &topk[i]); } // 建堆 for (i = (k - 1 - 1) / 2; i >= 0; i--) { AdjustDown(topk, k, i); } // 剩余n - k 个数分别于根元素比较 int val = 0; int ret = fscanf(pfout, "%d", &val); while (ret != EOF) { if (val > topk[0]) { topk[0] = val; AdjustDown(topk, k, 0); } ret = fscanf(pfout, "%d", &val); } for (i = 0; i < k; i++) { printf("%d ", topk[i]); } free(topk); fclose(pfout); } void CreateNData() { int n = 10000; const char* file = "data.txt"; FILE* pfin = fopen(file, "w"); if (pfin == NULL) { perror("TestTopK fopen"); return; } int i = 0; for (i = 0; i < n; i++) { int x = rand() % 10000; fprintf(pfin, "%d\n", x); } fclose(pfin); } int main() { srand((unsigned int)time(NULL)); CreateNData(); PrintfTopK("data.txt", 10); return 0; }
效果如下:
C语言数据结构堆排序、向上调整和向下调整的时间复杂度的计算、TopK问题等的介绍
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。