堆排序和TOP-K问题
Posted 银背欧尼酱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆排序和TOP-K问题相关的知识,希望对你有一定的参考价值。
前言
1. 建堆的时间复杂度
-
快速排序(快排)O(NlogN)
-
以插入的方式建堆O(NlogN)
-
向下调整来建堆O(N)
2. 堆的排序
堆排序即利用堆的思想进行排序。
步骤:
1.建堆,排升序建大堆,排降序建小堆
2.排序 -->利用堆删除的思想排序。即先让头尾结点交换,再把堆中元素个数减1,将交换后的二叉树(此时已经不是堆了)利用向下调整法重新变成堆。循环往复。直到排好整个数组。
代码实现
//向下调整
void HeapAdjust(int array[], int size, int parent)
{
int child = parent * 2 + 1;
while (child < size)
{
if (child+1 < size && array[child + 1] > array[child])
child += 1;
if (array[child] > array[parent])
{
int temp = array[child];
array[child] = array[parent];
array[parent] = temp;
parent = child;
child = parent * 2 + 1;
}
else
{
return;
}
}
}
void HeapSort(int array[], int size)
{
int end = size-1;
// 1.建堆 升序-->大堆 降序-->建小堆
for (int root = (size - 2) / 2; root >= 0; root--)
{
HeapAdjust(array, size, root);
}
// 2. 利用堆删除的思想来进行排序
while (end > 0)
{
Swap(&array[end], &array[0]);
HeapAdjust(array, end, 0);
end--;
}
}
3. TOP-K问题
TOP-K问题即给出一组庞大的数据,要求找出数值最大或最小的前K个数。
如果用常规的排序算法,时间复杂度为O(N^2),时间复杂度过大。所以这里使用堆的思想来解决。
步骤(此处举例取数值最大的K个数):
- 用K个元素建小堆,因为是取最大的数。
- 使用剩余的N-K个数和堆顶元素比较,如果大于堆顶元素,则替换掉堆顶,并用向下调整法把数列重新调整为小堆。
- 这样做可以不断地让堆中最小的数值出局。当用N-K个元素依次和堆顶比较替换后,堆中的元素就是原数据组中最大的K个元素。
时间复杂度:
建堆的时间复杂度:O(K)。
剩余N-K个元素每次都向下调整:O(N-K)*log(K)。
所以总的时间复杂度为O(N);
代码实现参考上面的建堆和堆调整的代码即可。
总结
以上就是今天要讲的内容,介绍了几种建堆方法的时间复杂度,和利用堆排序的思想。配合博客《堆的初始化及增删查改等操作》食用更佳。
以上是关于堆排序和TOP-K问题的主要内容,如果未能解决你的问题,请参考以下文章