import java.util.Arrays;
public class HeapSort {
/**
* 找到数组中下标为i的元素的父节点在数组中所在的下标位置
*
* @param i
* 要操作的元素下标
* @return 下标为i的元素的父节点在数组中所在的下标位置
*/
static int parent(int i) {
return ((i + 1) >> 1) - 1;
}
/**
* 找到数组中下标为i的元素的左孩子节点在数组中所在的下标位置
*
* @param i
* 要操作的元素下标
* @return 下标为i的元素的左孩子节点在数组中所在的下标位置
*/
static int left(int i) {
return right(i) - 1;
}
/**
* 找到数组中下标为i的元素的右孩子节点在数组中所在的下标位置
*
* @param i
* 要操作的元素下标
* @return 下标为i的元素的右孩子节点在数组中所在的下标位置
*/
static int right(int i) {
return (i + 1) << 1;
}
static void swap(int array[], int first, int second) {
int temp = array[first];
array[first] = array[second];
array[second] = temp;
}
/**
* 将数组array中的以root为起点连续size+1个元素调整为大顶堆,但前提是root的左右两棵子树都是大顶堆
*
* @param array
* @param root
* @param size
*/
static void selectMax(int array[], int root, int size) {
int largest = root;
int left = left(root);
int right = right(root);
if (left <= size && array[left] > array[largest]) {
largest = left;
}
if (right <= size && array[right] > array[largest]) {
largest = right;
}
if (largest != root) {
swap(array, largest, root);
selectMax(array, largest, size);
}
}
/**
* 建堆
*
* @param array
* @param size
*/
static void makeHeap(int array[], int size) {
if (array == null || size <= 0) {
return;
}
for (int i = size / 2; i >= 0; i--) {
selectMax(array, i, size);
}
}
/**
* 堆排序
*
* @param array
*/
static void heapSort(int array[]) {
if (array == null || array.length == 0) {
return;
}
makeHeap(array, array.length - 1);
for (int i = array.length - 1; i >= 1; i--) {
swap(array, 0, i);
selectMax(array, 0, i - 1);
}
}
public static void main(String[] args) {
int[] array = { 1, 2, 3, 4, 5, 6, 9, 8, 7, 10, 11, 1001, 991, 188, 188, 34, 34, 34, 33, 3, 4, 34, 343, 0 };
System.out.println("排序前:");
System.out.println(Arrays.toString(array));
heapSort(array);
System.out.println("排序后:");
System.out.println(Arrays.toString(array));
}
}