系列文章目录
提示: 以下是其他排序算法的链接🔗
文章目录
- 系列文章目录
- 什么是堆排序?
什么是堆排序?
堆排序(Heap Sort)是一种基于二叉堆数据结构的排序算法。它利用堆的性质进行排序,具体来说是利用最大堆(或最小堆)来进行升序(或降序)排序。
堆排序的步骤如下:
- 构建最大堆(或最小堆):将待排序的序列构建成一个最大堆(或最小堆)。最大堆的性质是父节点的值大于等于其子节点的值,最小堆的性质是父节点的值小于等于其子节点的值。
- 交换堆顶元素和最后一个元素:将堆顶元素(即最大值或最小值)与堆中最后一个元素交换位置。
- 重新调整堆:将剩余的元素重新调整为最大堆(或最小堆)。
- 重复步骤2和步骤3,直到堆中的元素只剩下一个。
- 最后,得到的序列就是有序的结果。
堆排序的时间复杂度为O(n log n),其中n是待排序序列的长度。堆排序是一种原地排序算法,不需要额外的空间。
代码模板(示例):
class Solution {
public int[] sortArray(int[] nums) {
heapSort(nums);
return nums;
}
/**
* 堆排序
* O(NlogN)
* 不稳定
*/
public static void heapSort(int[] arr) {
int n = arr.length;
// 从下到上先调整为大根堆
// i 的值从 0 开始,为每层根节点的下标
for (int i = n / 2 - 1; i >= 0; i--) {
shiftDown(arr, i, n);
}
for (int i = n - 1; i >= 0; i--) {
// 将最大值(即arr [0] 调整到数组最后
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
// 此时最大的元素已经调整完成
// 忽略掉最后一个元素,再次调整为大根堆
shiftDown(arr, 0, i);
}
}
/**
* 调整子树为大根堆
* @param arr
* @param parent 根节点下标
* @param size 数组大小
*/
private static void shiftDown(int[] arr, int parent, int size) {
int child = parent * 2 + 1;
while (child < size) {
// 选出较大的子节点
if (child + 1 < size && arr[child] < arr[child + 1]) {
child++;
}
if (arr[child] > arr[parent]) {// 子大于父
// 交换最大值
int tmp = arr[parent];
arr[parent] = arr[child];
arr[child] = tmp;
// 调整交换后的子树
parent = child;
child = parent * 2 + 1;
} else {// 子小于父,已经是大根堆了
break;
}
}
}