把一个数组 构建为大顶堆的过程
根据完全二叉树的性质 计算出来 某个节点 父节点的index 左孩子的index 右孩子的index
/**
* 堆排序
*
*/
public class MyHeapSort extends App {
/**
* 把数组构建为大顶堆
*/
private static void buildMaxHeap(int[] arr, int len) {
//找出最后一个节点 的索引值
int lastnodeIndex = len-1 ;
//找出最后一个节点 的父亲节点的索引值 (依据完全二叉树的性质 )
int startparent = (lastnodeIndex-1)/2;
//依次堆化
for (int i = startparent; i >= 0; i--) {
heapify(arr,i,len);
}
}
public static void main(String[] args) {
int[] array = {6,7,88,3,5,77,112,999,3453,90,100,2,1} ;
//先把当前数组 构建为大顶堆 那么他的第一个元素 一定是最大的
//下面的 swap(array,i,0); 是把第一个元素 和最后一个元素 进行交换
// 那么最大的元素就排好了
buildMaxHeap(array,array.length);
//每走一趟 本次最大的元素 就放到了最后的位置
for(int i=array.length-1;i>=0;i--){
//把最大的元素 和 最后位置的元素进行交换
swap(array,i,0);
//从index为0 的位置 重新堆化
heapify(array,0,i);
}
logger.info(Arrays.toString(array));
}
/**
*
* 把数组arr 的第i个元素 和 第j个元素 交换
*
*/
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/**
* 堆化函数
* @param arr 数组
* @param i 从当前index开始 进行堆化
* @param len 数组的长度
*/
private static void heapify(int[] arr, int i, int len) {
//当前index 左孩子的索引值
int left = 2 * i + 1;
//当前index 右孩子的索引值
int right = 2 * i + 2;
int largest = i;
//如果左孩子 大于 根节点 交换
if (left < len && arr[left] > arr[largest]) {
largest = left;
}
//如果右孩子 大于 根节点 交换
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
//说明 当前节点 不符合大顶堆
if (largest != i) {
//进行交换
swap(arr, i, largest);
//从当前节点 重新进行堆化
heapify(arr, largest, len);
}
}
}