当前位置:网站首页>堆的应用:堆排序和TOP-K问题
堆的应用:堆排序和TOP-K问题
2022-08-03 01:50:00 【underratedtang】
堆的应用
堆排序
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
利用堆删除的思想来进行排序。以升序为例,建立大根堆后,交换堆顶和堆末尾的数据并减少堆的长队,再利用向下调整算法重新建立堆。这样最大的数据就成功到数组末尾了。
HeapSort的代码:
void HeapSort(int* a, int n)
{
//升序建大堆,降序建小堆
//向下建堆效率高
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(a, n, i);
}
int end = n - 1;
while (end > 0)
{
Swap(&a[0], &a[end]);
AdjustDown(a, end, 0);
end--;
}
}
堆排序使用堆来选数,效率较高。
时间复杂度:O(N*logN);
空间复杂度:O(1)
稳定性:不稳定
TOP-K问题
TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量N都比较大,而K相对较小。
对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,基本思路如下:
- 用数据集合中前K个元素来建堆。要求前k个最大的元素,则建小堆;前k个最小的元素,则建大堆
- 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素(这样需要开辟的数组大小仅仅是K了,节省了空间)
将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。
TOP-K问题代码:
void PrintTopK(int* a, int n, int k)
{
//找大数建小堆
//建堆 用a中前k个元素建堆
int* kMinHeap = (int*)malloc(sizeof(int) * k);
if (kMinHeap == NULL)
{
printf("malloc fail\n");
exit(-1);
}
for (int i = 0; i < k; i++)
{
kMinHeap[i] = a[i];
}
for (int i = (k - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(kMinHeap, k, 0);
}
//将剩余n-k个元素一次与堆顶元素交换,不满则替换
for (int j = k; j < n; j++)
{
if (a[j] > kMinHeap[0])
{
kMinHeap[0] = a[j];
AdjustDown(kMinHeap, k, 0);
}
}
for (int j = 0; j < k; j++)
{
printf("%d ", kMinHeap[j]);
}
printf("\n");
}
边栏推荐
猜你喜欢
随机推荐
Introduction to agile development
5.软件测试-----自动化测试
复杂多层布局的初级智能文本提示器
45部署LVS-DR群集
Shell脚本乘法口诀等小实验
MySQL删库不跑路
Excel 如何比较两列字符串是否相同?
js垃圾回收机制
lombok 下的@Builder和@EqualsAndHashCode(callSuper = true)注解
11-security认证.md
46LVS+Keepalived群集
numpy PIL tensor之间的相互转换
Brute force recursion to dynamic programming 07 (516. Longest palindrome subsequence)
软件定义网络实验之SDN网络简单管理及开发
怎么从零编写一个 v3 版本的 chrome 浏览器插件实现 CSDN 博客网站的暗黑和明亮主题切换?
Violence recursion to dynamic programming 08 (pony go chess)
Kubernetes:(八)调度约束和故障排查
扩展卡尔曼滤波【转】
List转Map的几种方式
PHICOMM(斐讯)N1盒子 - Armbian5.77(Debian 9)刷入EMMC









