介绍
堆排序:(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。
堆是一个近似完全二叉树的结构,并同时满足堆积的性质:
即子结点的键值或索引总是小于(或者大于)它的父节点。
在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。
堆中定义以下几种操作:
最大堆调整(Max Heapify):
将堆的末端子节点作调整,使得子节点永远小于父节点
创建最大堆(Build Max Heap):
将堆中的所有数据重新排序
堆排序(HeapSort):
移除位在第一个数据的根节点,并做最大堆调整的递归运算
源码
package nono.sort;
import java.util.Arrays;
/**
* 堆排序
* @author Nonoas
*/
public class HeapSorter {
/**
* 堆排序
* @param array 源数组
* @param last 结尾下标
*/
public static void heapSort(int[] array, int last) {
if (last <= 0)
return;
for (int i = (last - 1) / 2; i >= 0; i--) { // 从最后一个根节点往前依次堆化
heapify(array, i, last);
}
swap(array, 0, last--);
heapSort(array, last);
}
/**
* 堆化一棵子树,即大的当爹,小的当儿子
* @param array 源数组
* @param pos 节点位置
*/
private static void heapify(int[] array, int first, int last) {
if (first > (last - 1) / 2)
return;// 递归出口
int max = first, left = 2 * first + 1, right = 2 * first + 2;
if (left <= last) //检查左孩子是否存在
max = array[max] > array[left] ? max : left;//比较根与左孩子大小
if (right <= last) //检查右孩子是否存在
max = array[max] > array[right] ? max : right;//比较根于右孩子的大小
if (max != first) //如果根不是最大的,则交换根与最大值
swap(array, max, first);
heapify(array, left, last);// 对左孩子递归
heapify(array, right, last);// 对右孩子递归
}
/**
* 交换数组两个位置的值
* @param array 源数组
* @param i 第一个位置
* @param j 第二个位置
*/
private static void swap(int[] array, int i, int j) {
array[i] = array[i] ^ array[j];
array[j] = array[i] ^ array[j];
array[i] = array[i] ^ array[j];
}
public static void main(String[] args) {
int[] a = { 5, 4, 7, 9, 6, 3, 8, 2, 1 };
System.out.println("排序前:"+Arrays.toString(a));
heapSort(a, a.length - 1);
System.out.println("排序后:"+Arrays.toString(a));
}
}
输出结果
排序前:[5, 4, 7, 9, 6, 3, 8, 2, 1]
排序后:[1, 2, 3, 4, 5, 6, 7, 8, 9]