堆排序过程:先将数组调整为大顶堆(或者小顶堆),然后再对数组的每一个成员逐一与第一个元素对换并调整。
import java.util.Arrays;
public class MyHeap {
public static void main(String args[]) {
int arr[] = {8, 7, 4, 1, 2, 3, 6, 5, 9};
sortASC(arr);
System.out.println(Arrays.toString(arr));
// sortDESC(arr);
// System.out.println(Arrays.toString(arr));
}
/**
* 升序 ,用大顶堆
*
* @param arr
*/
public static void sortASC(int arr[]) {
for (int i = arr.length / 2 - 1; i >= 0; i--) {
adjustBigHeap(arr, i, arr.length);//调整最初状态
}
for (int j = arr.length - 1; j >= 0; j--) {//对数组的每个元素进行调整,j就是调整的长度
swap(arr, 0, j);//调换0与j位置上的数,在调整的时候能够将j的值调到最高的位置
adjustBigHeap(arr, 0, j);//,然后对堆进行调整
}
}
/**
* 调整数组的以第i个为根节点的树
*
* @param arr
* @param i
* @param length
*/
public static void adjustBigHeap(int[] arr, int i, int length) {
int temp = arr[i];
for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {//先对左子节点进行比较
if (k + 1 < length && arr[k] < arr[k + 1]) {//如果左子节点比右子节点小,k就+1
k++;
}
if (arr[k] > temp) {//最大子节点与temp比较
arr[i] = arr[k];//如果最大子节点比父亲大,就对换,
i = k;//标记temp需要存放的地方
} else break;
}
arr[i] = temp;
}
/**
* 降序,用小顶堆
*
* @param arr
*/
public static void sortDESC(int arr[]) {
for (int i = arr.length / 2 - 1; i >= 0; i--) {
adjustSmallHeap(arr, i, arr.length);
}
for (int j = arr.length - 1; j >= 0; j--) {
swap(arr, 0, j);
adjustSmallHeap(arr, 0, j);
}
}
/**
* 调整小顶堆,
*
* @param arr
* @param i
* @param length
*/
public static void adjustSmallHeap(int[] arr, int i, int length) {
int temp = arr[i];
for (int j = 2 * i + 1; j < length; j = 2 * j + 1) {//
if (j + 1 < length && arr[j] > arr[j + 1]) {
j++;
}
if (arr[j] < temp) {
arr[i] = arr[j];
i = j;
} else break;
}
arr[i] = temp;
}
public static void swap(int arr[], int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}