import java.util.Arrays;
/**
* 创建时间:2019年3月8日 下午3:56:43
*
* @author 张十一先生 类说明: 堆排序,利用二叉树构造出大堆来即所有的父节点都要比子节点要大->取堆顶最大的元素去和数组的首元素交换
* 这个元素放在数组最后一个,不再移动,通过迭代不断改造二叉树为大堆,在把元素依次放入。最后成为有序数列。
*/
public class HeapSort {
public static void main(String[] args) {
int[] arr = new int[] { 1, 5, 7, 8, 2, 3, 6 };
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void heapSort(int arr[]) {
int start = (arr.length - 1 - 1) / 2;
// 从最后一个父节点开始,再到下一个父节点(直接递减就可以,若无子节点就不会处理)
for (int i = start; i >= 0; i--) {
maxHeap(i, arr.length, arr);
}
// 开始把堆定的元素跟数组的首位交换
for (int i = arr.length - 1; i >= 0; i--) {
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
maxHeap(0, i, arr);
}
}
// 进行大堆改造
public static void maxHeap(int index,int size,int [] arr){
// 根据顺序存储的二叉树知识,左子树的节点为index*2+1,右子树的节点为index*2+2
int leftNode = index * 2 + 1;
int rightNode = index * 2 + 2;
int max = index;
// leftNode < size,该出的判断是调换元素过程中过滤掉没有子树的节点。
if (leftNode < size && arr[leftNode] > arr[max]) {
max = leftNode;
}
if (rightNode < size && arr[rightNode] > arr[max]) {
max = rightNode;
}
if (max != index) {
int temp = arr[max];
arr[max] = arr[index];
arr[index] = temp;
// 改动后可能当前节点满足大堆,但是他的子节点的结构首影响所以要对改动后的 子节点迭代处理
maxHeap(max, size, arr);
}
}
}