/**
* 堆排序<br>
* 堆排序是一种常用的排序方法,它通过构建二叉堆来实现。<br>
* 在堆数据结构中,每个节点都满足父节点大于等于或小于等于两个子节点的关系,称为大根堆或小根堆。<br>
* 堆排序使用堆数据结构来排序数组,它分为两个阶段:建堆和排序<br>
* 堆排序的时间复杂度是O(NlogN),它的空间复杂度是O(1)。在实践中,堆排序常常是最优的选择之一。
* @param arr
*/
public static void heapSort(int arr[]) {
int n = arr.length;
// 构建大根堆(升序排序)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// 一个个取出堆顶元素进行排序
for (int i = n - 1; i >= 0; i--) {
// 将当前最大值交换到末尾
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// 重新构建大根堆
heapify(arr, i, 0);
}
}
private static void heapify(int arr[], int n, int i) {
int largest = i; // 初始化最大元素节点为父节点
int left = 2 * i + 1; // 左节点索引
int right = 2 * i + 2; // 右节点索引
// 如果左子节点比父节点大,则更新最大元素节点为左子节点
if (left < n && arr[left] > arr[largest])
largest = left;
// 如果右子节点比父节点大,则更新最大元素节点为右子节点
if (right < n && arr[right] > arr[largest])
largest = right;
// 如果最大元素节点不是父节点,则交换父节点和最大元素节点
if (largest != i) {
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
// 继续构建大根堆
heapify(arr, n, largest);
}
}
public static void main(String[] args) {
int[] arr = new int[] { 4, 3, 2, 5, 12, 6, 8, -1, 55, 67, 54, 23 };
heapSort(arr);
System.out.println(Arrays.toString(arr));
}