package sort;
import java.util.Arrays;
/**
* 堆排序:利用树形结构的知识(二叉树、大顶堆、小顶堆)
* 先转化为大顶堆,再交换数组首尾元素值,交换后最大值位于数组尾部;将前n-1个元素转化为大顶堆,再交换,以此类推
* 时间复杂度为O(nlogn),性能远超冒泡、简单选择、直接插入排序
* @author:zhaidc@qq.com
* @date:2022年2月26日 下午10:59:27
*/
public class HeapSort {
//测试用例
public static void main(String[] args) {
int[] arr = new int[] {9,6,8,7,0,1,10,4,2};
heapSort(arr);
System.out.print(Arrays.toString(arr));
}
/**
* 堆排序
* @param arr 待排序数组
*/
private static void heapSort(int[] arr) {
int len = arr.length;
int index = (len - 2) / 2;
toBigHeap(arr, index, len - 1);
for(int i = len - 1;i > 0;i--) {
swap(arr, 0, i);
toBigHeap(arr, 0, i - 1);
}
}
/**
* 将待排序数组的前end个元素转化为大顶堆
* @param arr 待排序数组
* @param index 最后一个非叶结点
* @param end 数组需要转化大顶堆的部分的末位置索引
*/
private static void toBigHeap(int[] arr, int index, int end) {
while(index >= 0) {
int max = index;
//若存在左孩子且比左孩子小,则max指向左孩子
if(2 * index + 1 <= end && arr[index] < arr[2 * index + 1]) {
max = 2 * index + 1;
}
//若存在右孩子且(注意,此处用max指向的值比较)比右孩子小,则max指向右孩子
if(2 * index + 2 <= end && arr[max] < arr[2 * index + 2]) {
max = 2 * index + 2;
}
//若max不指向index,则交换
if(max != index) {
swap(arr, index, max);
//防止交换下来的元素比其左右孩子小,再次递归
toBigHeap(arr, max, end);
}
index--;
}
}
/**
* 交换数组的两个索引的元素值
* @param arr 待交换数组
* @param i
* @param j
*/
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
堆排序——Java实现
最新推荐文章于 2024-11-08 14:58:24 发布