堆排序是选择排序算法的进阶,也就是通过二叉树节点存储数组,并通过root节点存储最值与二叉树最后一个节点进行交换完成排序,降低了时间复杂度。在大数据时代,堆排序常用于处理Top-K问题。
- 排序对象:数组
- 时间复杂度:
- 空间复杂度:
- 是否稳定:否
堆排序分为大根堆和小根堆,大根堆的root节点是最大值,小根堆的root节点是最小值,通常再进行升序排序的时候会建立大根堆,再进行降序排序的时候会建立小根堆。
在实际应用中,堆排序常用于解决Top-K问题。
void Swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
// 建大根堆,向下调整
void DownAdjust(int* arr, int parent, int n)
{
int child = parent * 2 + 1;
while (child < n)
{
if (child + 1 < n && arr[child] < arr[child + 1])
child++;
if (arr[parent] < arr[child])
{
Swap(&arr[parent], &arr[child]);
parent = child;
child = child * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(int* arr, int n)
{
int parent = (n - 2) / 2; // 最后一个节点的父节点
while (parent >= 0)
{
DownAdjust(arr, parent, n);
--parent;
}
while (--n)
{
Swap(&arr[0], &arr[n]);
DownAdjust(arr, 0, n);
}
}
大根堆构建过程:
// 示例数组
int arr[20] = {
9, 3, 5, 7, 9, 0, 2, 4, 6, 8,
5, 5, 5, 0, 0, 1, 3, 5, 8, 6
};