目录
1.堆排序算法原理
1)构建初始堆
将待排序的数组元素构建成一个最大堆(或最小堆) 从最后一个非叶子节点开始,向上调整每个子树,使其成为一个最大堆。
2)堆调整与排序
将最后元素 与 堆顶值 交换,这样最大元素就在数组的末尾
堆调整将交换后的新堆顶元素向下调整,使其重新成为一个最大堆。 重复:持续进行以上步骤,直到堆的大小减少到1。
3)时间复杂度
每次调整的复杂度是 O(log n),共需要 n 次调整,所以总时间复杂度是 O(n log n)。
2.java代码实现(可运行)
public class HeapSort {
public void HeapSort(int[] arr) {
int length = arr.length;
// 1. build heap
//从 最后一个非叶子节点开始,向数组左边建立堆,直到跟节点,即数组【0】
for (int i = length / 2 - 1; i >= 0; i--) {
heapify(arr, length, i);
}
// 2. sort
for (int j = length - 1; j > 0; j--) {
// 将最后元素 与 堆顶值 交换,这样最大元素就在数组的末尾
swap(arr, 0, j);
// 因为新的堆顶元素变更了,需要重新调整堆
heapify(arr, j, 0);
}
}
/**
* 维护堆有序性
*
* @param src
* @param len
* @param index
*/
private void heapify(int[] src, int len, int index) {
int largest = index;
int left = 2 * index + 1;
int right = 2 * index + 2;
// 更新最大节点的index
if (left < len && src[left] > src[index]) {
largest = left;
}
if (right < len && src[right] > src[largest]) {
largest = right;
}
// 说明 最大节点 已经不是index 索引的值
if (index != largest) {
//调整 父 子节点值,保证有序
swap(src, index, largest);
//继续调整堆,index = largest
heapify(src, len, largest);
}
}
private void swap(int[] arr, int src, int dst) {
int temp = arr[src];
arr[src] = arr[dst];
arr[dst] = temp;
}
public static void main(String[] args) {
HeapSort heapSort = new HeapSort();
int[] a = {1, 34, 2, 5, 4, 17, 22};
// int[] arr = {10, 7, 8, 6, 4, 2, 1, 3, 5, 9};
heapSort.HeapSort(a);
System.out.println(Arrays.toString(a));
}
}```