【圖解排序】堆排序(Java)

介紹

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章