《排序演算法》——堆排序(大頂堆,小頂堆,Java)

Thinkgamer_gyt發表於2015-07-30
十大演算法之堆排序:

堆的定義如下:
  n個元素的序列{k0,k1,...,ki,…,k(n-1)}當且僅當滿足下關係時,稱之為堆。
  " ki<=k2i,ki<=k2i+1;或ki>=k2i,ki>=k2i+1.(i=1,2,…,[n/2])"

  若將和此次序列對應的一維陣列(即以一維陣列作此序列的儲存結構)看成是一個完全二叉樹,

  則完全二叉樹中每一個節點的值的都大於或等於任意一個位元組的值(如果有的話),稱之為大頂堆。

  則完全二叉樹中每一個節點的值的都小於或等於任意一個位元組的值(如果有的話),稱之為小頂堆。

  由此,若序列{k0,k1,…,k(n-1)}是堆,則堆頂元素(或完全二叉樹的根)必為序列中n個元素的最小值(或最大值)。

  倘若給堆中每一個節點都賦予一個整數值標籤,根節點被標記為0,對於每一個標記為i的節點,其左子節點(若存在的話)被標記為2*i+1,其右子節點(若存在的話)被標記為2*i+2,對於一個標記為i的非根節點,其父節點被標記為(i-1)/2。使用這個標記,我們能夠將堆儲存在陣列中,節點儲存在資料中的位置就使其標籤。


package sort;

import java.util.Arrays;

/*
 * 堆排序
 * 堆的定義:滿足 Ki <= K2i+1 Ki<=K2i+2 為小頂堆,滿足 Ki >= K2i+1 Ki>=K2i+2 為大頂堆
 * 此為大頂堆的程式碼例項,小頂堆類似
 */
public class duiSort {

	static int[] arr  = {
		16,7,3,20,17,8                   //定義待排序陣列
	}; 
	public static void main(String[] args) {
		
		buildHeap();//建立大頂堆並排序
		System.out.println("排序好的為:" + Arrays.toString(arr));
	}
	
	private static void buildHeap() {
		// TODO Auto-generated method stub
		int len = arr.length;
		for(int i =len/2 -1 ;i>=0;i--)            //建立大頂堆
		{
			sortHeap(i,len);
		}
		System.out.println("建立好的大頂堆如下:" + Arrays.toString(arr));
		for(int j = len-1; j >0; j --)        //對大頂堆進行排序
		{
			swap(0,j);
			sortHeap(0,j);
		}
	}

	private static void sortHeap(int i, int len) {
		// TODO Auto-generated method stub
		int left = 2*i+1;         //定義左節點
		int right = 2*i +2;     //定義右節點
		int large = 0;         //存放三個節點中最大節點的下標
		if(len >left && arr[left] > arr[i])    //如果左孩子大於根節點 將左孩子下標賦值給large
			large = left; 
		else                                                   //否之,將根節點下標賦值給large
			large = i;
		
		if(len > right && arr[right] > arr[large])
			large = right;                                //若右孩子節點大於根節點,把右孩子節點下標賦值給large
		
		if(large != i)                  //若最大節點的下標不等於根節點的下標時,交換其值
		{
			swap(large,i);
			sortHeap(large,len);
		}
	}
	//交換對應下標值
	private static void swap(int m, int n) {
		// TODO Auto-generated method stub
		int temp ;
		temp = arr[m];
		arr[m] = arr[n];
		arr[n] = temp;
	}
}


相關文章