算法學習之排序學習之堆排序和如何建堆

堆是一種特殊的數據結構,是一種完全二叉樹,分爲大根堆(根節點的值大於孩子節點)和小根堆(根節點小於孩子節點),好了,不廢話了,怎麼建堆和堆排序直接貼代碼如下(其中調整堆,建堆,堆排序的具體步驟均有註釋,還是代碼詳細,這樣看了一目瞭然。。呵呵。。):(這個是java實現的大根堆。。)
package test;

public class StackSort {

	public static void main(String[] args) {
		int[] a = { 26, 5, 77, 1, 61, 11, 59, 15, 48, 19 };
		Sort(a);
	}
	//堆排需方法
	public static void Sort(int[] a) {
		int n = a.length;//取得數組總長度,及堆最大的序號
		int temp = 0;

		Display(a, "Before sort : ");
         //這是建堆的過程,一次從倒數第二層的根節點開始調整堆,即數組下標爲i/2開始,一直到頂層根節點,這樣就建好堆了。。
		for (int i = n / 2; i > 0; i--) {
			Adjust(a, i - 1, n);//從倒數第二層的最後一個根節點開始調整堆
			Display(a, "建立大根堆 : ");
		}
		System.out.println("---------------------------------------");
		for (int i = n - 2; i >= 0; i--) {//這是堆排序的具體算法,思想是每次取出堆的最頂層根節點,即數組下標爲0,然後與最後一個節點即i+1交換,這樣對於大根堆而言,最大值總是在後面。。循環過後就能排序了。。
			temp = a[i + 1];//取出最後一個元素
			a[i + 1] = a[0];//取出第一個元素,即頂層根節點
			a[0] = temp;//交換位置

			Adjust(a, 0, i + 1);//調整堆
			Display(a, "重建立大根堆 : ");
		}

		Display(a, "After  sort : ");
	}
	/**
	 * 調整堆的方法
	 * @param a 要調整的數組,即堆
	 * @param i 調整的根節點,即起始位置
	 * @param n 要調整的終止位置
	 */
	public static void Adjust(int[] a, int i, int n) {
		int j = 0;
		int temp = 0;

		temp = a[i]; //取出根節點
		j = 2 * i + 1;  //左孩子節點

		while (j <= n - 1) {
			if (j < n - 1 && a[j] < a[j + 1])//比較左右孩子,取出較大的孩子
				j++;

			if (temp >= a[j]) //如果根節點大於孩子節點則退出循環,不用調整
				break;

			a[(j - 1) / 2] = a[j];//較大的孩子節點值賦值給根節點

			j = 2 * j + 1;//繼續尋找左孩子
		}

		a[(j - 1) / 2] = temp;//將根節點賦值給最後一個空出來的節點
	}
	//打印堆內容
	public static void Display(int[] a, String str) {
		System.out.println(str);

		for (int i = 0; i < a.length; i++)
			System.out.print(a[i] + " ");

		System.out.println();
	}

}
運行結果如下:

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