介紹
堆排序:(英語: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]