任何一个数组都可以转换为顺序存储的完全二叉树,且有以下性质:
第n个节点的左子节点是:2 * n + 1;
第n个节点的父节点是:(n - 1) / 2;
堆排序原理:
(1)从最后一个不是叶子节点的节点开始往前递归,分别将其子树调整为大顶堆;
(2)调整为大顶堆的过程中交换数值可能打破已有的大顶堆规则,所以在调整每个父节点子树为大顶堆时需要递归;
(3)每次将数组调整为大顶堆后,将首尾元素交换,将最大值放在数组最后的位置;
(4)递归操作。
package tree;
import java.util.Arrays;
/**
* 堆排序
*
* @author lyq
* @create 19-3-26
*/
public class HeapSort {
public static void main(String[] args) {
int[] arr = {6,1,4,0,5,3,10,9};
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void heapSort(int[] arr){
for (int j = arr.length-1;j >= 0;j--){
for (int i = j/2;i>=0;i--){
bigHeap(arr,i,j);
}
int max = arr[0];
arr[0] = arr[j];
arr[j] = max;
}
}
/**
* 将一个数组转为大顶堆
* @param arr 要转换的数组
* @param index 最后一个非叶子节点的位置
* @param size 要转换的元素个数
*/
public static void bigHeap(int[] arr,int index,int size){
int max = index;
int leftNode = 2 * index + 1;
int rightNode = 2 * index + 2;
if (leftNode <= size && arr[leftNode] > arr[max]){
max = leftNode;
}
if (rightNode <= size && arr[rightNode] > arr[max]){
max = rightNode;
}
if (index != max) {
int temp = arr[index];
arr[index] = arr[max];
arr[max] = temp;
bigHeap(arr,max,size);
}
}
}