算法-堆排序
堆:
- 完全二叉树
- 父节点 i 的左右子节点为 2i+1, 2i+2,且 arr[i]>=arr[2i+1] && arr[i]>=arr[2i+2]
public class HeapSortMain {
/**
* 堆
* 父节点 i 的左右子节点为 2i+1, 2i+2,且 arr[i]>=arr[2i+1] && arr[i]>=arr[2i+2]
* <p>
* 对于大顶堆:arr[i] >= arr[2i + 1] && arr[i] >= arr[2i + 2]
* 对于小顶堆:arr[i] <= arr[2i + 1] && arr[i] <= arr[2i + 2]
*
* @param args
*/
public static void main(String[] args) {
int[] arr = new int[]{1, 4, 6, 20, 5, 2, 17, 11, 5, 3, 7, 8, 9, 10, 12, 13, 14, 15, 16, 18, 19, 20};
heapSort(arr);
print(arr);
}
public static void print(int[] arr) {
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
private static void heapSort(int[] arr) {
int n = arr.length;
// 建堆,从最后一个非叶子节点开始
for (int i = n / 2 - 1; i >= 0; i--) {
//首次调整堆, 获取最大值
adjustHeap(arr, i, n-1);
}
for (int i = n - 1; i > 0; i--) {
//交换堆顶元素和最后一个元素
swap(arr, 0, i);
//调整堆,排除已经排好的最后一个元素,而不是从n开始
adjustHeap(arr, 0, i - 1);
}
}
private static void swap(int[] x, int a, int b) {
int t = x[a];
x[a] = x[b];
x[b] = t;
}
private static void adjustHeap(int[] arr, int i, int n) {
int tmp, left, right;
tmp = arr[i];
for (left = 2 * i + 1; left < n; left = left * 2 + 1) { //沿关键字较大的孩子节点向下筛选
right = left + 1;
if (left < n && arr[left] < arr[right]) {
left = right; //j指向较大的孩子节点
}
if (tmp >= arr[left]) {
break;
}
arr[i] = arr[left];
i = left;
}
arr[i] = tmp;
}
}