堆是一种高效处理优先级问题的数据结构,尤其在动态数据流和排序场景中表现优异。本文将通过堆排序和TopK问题两个经典案例,深入解析堆的实际应用,并提供清晰的代码实现与原理分析。
初始数组:[4, 10, 3, 5, 1]
5//2 -1 =1
)开始调整。[10, 5, 3, 4, 1]
。💡 建堆的两种方式
//建大堆
//1.用向上调整建堆 时间复杂度O(nlogn),效率低,不推荐
for (i = 0; i < n; i++) {
AdjustUp(a, i);
}
//2.用向下调整建堆 时间复杂度O(n),推荐
for (i = (n - 1 - 1)/2; i >= 0; i--) {
AdjustDown(a, n, i);
}
这里调整算法不再赘述。如有疑问,请学习“堆的实现” 或者与我交流哦😀
10
与末尾1
→ 数组变为[1,5,3,4,10]
,有效堆范围减1。[1,5,3,4]
为最大堆 → [5,4,3,1]
。[1,3,4,5,10]
。//升序排序,用大根堆;
//降序排序,用小根堆。
void HeapSort(HPDataType* a,int n)
{
//排升序
int i = 0;
//建大堆
//1.用向上调整建堆 时间复杂度O(nlogn),效率低,不推荐
/*for (i = 0; i < n; i++) {
AdjustUp(a, i);
}*/
//2.用向下调整建堆 时间复杂度O(n),推荐
for (i = (n - 1 - 1)/2; i >= 0; i--) {
AdjustDown(a, n, i);
}
//排序
int end = n - 1;
while (end > 0) {
swap(a, &a[end]);
AdjustDown(a, end, 0);
end--;
}
for (i = 0; i < n; i++) {
printf("%d ", a[i]);
}
}
rand
生成随机数void CreateNumber()
{
int n = 10000;
//时间种子
srand((unsigned int)time(0));
const char* file = "data.text";
FILE* fp = fopen(file, "w");
if (fp == NULL) {
perror("fopen fail");
return;
}
//写入文件
for (size_t i = 0; i < n; ++i)
{
int x = rand() % 10000;
fprintf(fp, "%d\n", x);
}
fclose(fp);
fp = NULL;
}
void PrintTopK(const char* file, int k)
{
int* topk = (int*)malloc(sizeof(int) * k);
if (topk == NULL) {
perror("fopen fail");
return;
}
FILE* fp = fopen(file, "r");
if (fp == NULL) {
perror("fopen fail");
return;
}
//建前k个数的小根堆
for (int i = 0; i < k; i++) {
fscanf(fp,"%d",&topk[i]);
}
for (int i = (k - 2) / 2; i >= 0; i--) {
AdjustDown(topk, k, i);
}
//遍历后面的数,若比堆top大,就覆盖并向下调整
int val = 0;
int ret = fscanf(fp, "%d", &val);
while (ret != EOF) {
if (val > topk[0]) {
topk[0] = val;
AdjustDown(topk, k, 0);
}
ret = fscanf(fp, "%d", &val);
}
for (int i = 0; i < k; i++) {
printf("%d ", topk[i]);
}
free(topk);
fclose(fp);
fp = NULL;
}
应用场景 | 核心思路 | 时间复杂度 | 空间复杂度 | 优势 |
---|---|---|---|---|
堆排序 | 构建堆 + 交换堆顶 | O(n log n) | O(1) | 原地排序,适合内存敏感 |
TopK问题 | 维护大小为K的最小堆 | O(n log K) | O(K) | 高效处理海量数据或数据流 |
Q1:为什么堆排序不如快速排序常用?
Q2:TopK问题能否用最大堆解决?
堆结构凭借其高效的插入删除和极致的空间利用率,在排序与筛选问题中占据独特地位。掌握堆排序与TopK的解法,能显著提升处理大规模数据的能力。理解原理后,可尝试手写堆实现或结合具体业务场景优化代码,进一步巩固知识。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有