/**
* 堆排序
* 用堆来实现的一种选择排序
*
* @author 小流慢影
* @date 2023年4月26日
*/
public class Heapsort {
public static void main(String[] args) {
int[] array = {5, 4, 3, 1, 2, 13, 12, 10, 11, 9, 7, 8, 6, 3, 5};
System.out.println("原数组:" + Arrays.toString(array));
heapsort(array);
System.out.println("排序后数组:" + Arrays.toString(array));
}
/**
* 堆排序
*
* @param array 数组
*/
public static void heapsort(int[] array) {
int lastFatherPoint = array.length / 2 - 1;
// 从最后一个父节点开始调整成堆,一直调整到根节点,那样根节点最后就是最大值
for (int i = lastFatherPoint; i >= 0; i--) {
adjustHeap(array, i, array.length - 1);
}
// 每次遍历把最大值都放在未排序数组的最后一个,直到遍历结束,数组就变成了从小到大排列的有序数组
for (int j = array.length - 1; j > 0; j--) {
swap(array, 0, j);
adjustHeap(array, 0, j - 1);
}
}
/**
* 整理成最大堆
*
* @param array 待组堆
* @param fatherPoint 父结点
* @param endPoint 结束结点
*/
public static void adjustHeap(int[] array, int fatherPoint, int endPoint) {
int fatherPointValue = array[fatherPoint];
for (int childPoint = getLeftChildPoint(fatherPoint); childPoint <= endPoint; childPoint = getLeftChildPoint(childPoint)) {
// 每次把子节点最大值和父节点换
if (childPoint + 1 <= endPoint && array[childPoint] < array[childPoint + 1]) {
childPoint++;
}
if (array[childPoint] > fatherPointValue) {
swap(array, fatherPoint, childPoint);
fatherPoint = childPoint;
} else {
// 第一次调整是从最后一个父节点开始遍历,所以可以保证子节点都是最大堆,只要两个子节点都小于父节点就可以直接终止了
break;
}
}
}
/**
* 获取左子节点
*
* @param fatherPoint 父节点
* @return 左子节点
*/
private static int getLeftChildPoint(int fatherPoint) {
return 2 * fatherPoint + 1;
}
/**
* 交换元素
*
* @param array 数组
* @param firstIndex 第一个元素的下标
* @param secondIndex 第二个元素的下标
*/
public static void swap(int[] array, int firstIndex, int secondIndex) {
int temp = array[firstIndex];
array[firstIndex] = array[secondIndex];
array[secondIndex] = temp;
}
}
Java堆排序
最新推荐文章于 2025-05-17 17:01:31 发布