import java.text.SimpleDateFormat;
import java.util.Date;
public class HeapSort {
public static void main(String[] args) {
// int[] arr = {4, 34, 19, 1, 9 ,-1};
// heapSort(arr);
// System.out.println(Arrays.toString(arr));
int[] arr = new int[80000000];
for (int i = 0; i < 80000000; i++) {
// Math.random()产生0-1之间的随即小数,需要乘以范围的大小指定范围
arr[i] = (int) (Math.random() * 80000000);
}
// System.out.println("排序前的数组是:" + Arrays.toString(arr));
// 标准化时间输出格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss sss");
Date date1 = new Date();
String strTime1 = sdf.format(date1);
System.out.println("排序前的时间为:" + strTime1);
// 进行排序
heapSort(arr);
// System.out.println("排序后的数组是:" + Arrays.toString(arr));
Date date2 = new Date();
String strTime2 = sdf.format(date2);
System.out.println("排序后的时间为:" + strTime2);
}
public static void heapSort(int[] arr) {
// 开始的位置是最后一个非叶子结点,下标为最后一个叶子结点的 (n - 1) / 2
int start = (arr.length - 2) / 2;
// 先调整为大顶堆
for (int i = start; i >= 0; i--) {
maxHeap(arr, arr.length, i);
}
// 将根结点与最后一个结点互换位置,循环调整最大结点之外的剩余结点
for (int i = arr.length - 1; i > 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// 互换位置之后,其他位置已经是大顶堆形式,只需调整根结点位置
maxHeap(arr, i, 0);
}
}
/**
* 把数组对应的二叉树调整为大顶堆
* @param arr 存放二叉树结点的数组
* @param size 调整范围的结点数量
* @param index 调整的结点位置
*/
public static void maxHeap(int[] arr, int size, int index) {
// 左子结点
int leftNode = 2 * index + 1;
// 右子结点
int rightNode = 2 * index + 2;
// 假设父结点的值最大
int max = index;
// 和子结点比较,找出数值最大的结点
if (leftNode < size && arr[leftNode] > arr[max]) {
max = leftNode;
}
if (rightNode < size && arr[rightNode] > arr[max]) {
max = rightNode;
}
// 如果子结点的数值大,交换位置
if (max != index) {
int temp = arr[index];
arr[index] = arr[max];
arr[max] = temp;
// 防止交换位置之后,破坏之前已经排好的该非叶子结点下面的堆,此时max指向子结点
maxHeap(arr, size, max);
}
}
}
algorithm:堆排序
最新推荐文章于 2025-04-01 17:32:58 发布