系列文章目录
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
堆排序原理
- 推排序:需要先将数组转换为大顶推。
- 大顶推:规范是 arr[k] 大于 arr[2k + 1] 和 arr[2k +2],其中k的取值范围0…(arr.length/2 -1)
- 得到大顶推之后, 就选取arr[0]的值和最后一个值替换,使得最后一个值最大。数组长度-1,并调整堆顶即可(因只有推顶不符合大顶推规范)。
每次循环第3步之后,直到数组长度为1为止。
Java代码实现
代码如下:
package com.study.algorithm;
import java.util.Arrays;
public class HeapSort {
public static void main(String[] args){
int[] arr = {10,9,2,12,30,1,5};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr){
int n = arr.length/2 - 1;
//推排序,从下到上, 从左到右
for(int i = n; i >=0; i--){
adjustHeap(arr,i,arr.length);
}
//经过上述排序, 已经完成大顶推的排序
//确保了 arr[k] > arr[2*k + 1] 和 arr[2*k + 2]
int tmp = 0;
//推排序的每次选取大顶推的首位与未尾值想替换, 实现每次排序在末尾的值在本次是最大的
//排出掉已排序的未尾即(i--),并对推进行重新调整,已符合大顶推规范
for(int i = arr.length - 1; i > 0; i--){
tmp = arr[i];
arr[i] = arr[0];
arr[0] = tmp;
//经过替换后,只有顶部不符合大顶推规范,其他不为是符合大顶推规范的
//在调整的时候,调整顶部位置即可
adjustHeap(arr,0,i);
}
}
/**
* 大顶推:规范 arr[k] > arr[2*k + 1] 和 arr[2*k +2]
* 调整大顶堆
* @param arr
* @param i 调整位置
* @param length 需要调整数组的长度
*/
public static void adjustHeap(int[] arr, int i, int length){
int tmp = arr[i];
for(int k = (2*i + 1); k < length; k = (k*2 +1)){
//获取左右子树的最大值索引
if((k + 1) < length && arr[k] < arr[k+1]){
k++;
}
//如果子树值大于父节点则替换
if(arr[k] > tmp){
arr[i] = arr[k];
i = k;
}else{
//否则退出循环,因在调整堆的时候是从下到上,从左到又的
//保证了k以下的堆是符合大顶推排序规范的
break;
}
}
arr[i] = tmp;
}
}