1. 程式人生 > >Java程式設計實現陣列排序——(三)選擇排序

Java程式設計實現陣列排序——(三)選擇排序

選擇排序的基本思想:每一趟在n-i+1(i=1,2,3...,n-1)個記錄中選取關鍵字最小的記錄作為有序序列的第i個記錄

一、簡單選擇排序

一趟簡單選擇排序:通過n-i次關鍵字之間的比較,從n-i+1個記錄中選出關鍵字最小的記錄,並和第i(1 ≦ i ≦ n)個記錄交換。

令 i 從 1 至 n-1 進行 n-1 趟選擇操作,其時間複雜度為O(n^2) 。

排序程式碼如下:

public class Demo03 {
	/*
	 * 一趟簡單選擇排序,返回其中最小值的下標
	 */
	private static int selectMinKey(int[] arr,int i){
		int temp=i;
		for(int k=i;k<arr.length;k++){
			if(arr[temp]>arr[k])
				temp=k;
		}
		return temp;
	}
	/*
	 * 選擇排序,若最小值不是當前元素,進行交換
	 */
	public static void selectSort(int[] arr){
		for(int i=0;i<arr.length;i++){
			int j=selectMinKey(arr, i);
			if(i!=j){
				int t=arr[i];
				arr[i]=arr[j];
				arr[j]=t;
			}
		}
	}
	public static void main(String[] args) {
		int[] arr=new int[10];
		arr[0]=0;
		arr[1]=15;
		arr[2]=98;
		arr[3]=105;
		arr[4]=45;
		arr[5]=8;
		arr[6]=51;
		arr[7]=18;
		arr[8]=66;
		arr[9]=21;
		selectSort(arr);
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
	}
}

二、樹形選擇排序

由上面我們可以知道,選擇排序關鍵字之間要進行n(n-1)/2次的比較,減少比較次數是改進簡單選擇排序演算法的思路之一。

樹形選擇排序又稱為錦標賽排序,它首先對n個記錄的關鍵字進行兩兩比較,然後在其中n/2個較小者當中再進行兩兩比較,反覆進行,直到選出最小的關鍵字為止。

樹形選擇排序存在著需要輔助儲存空間較多以及多餘比較的缺點,其時間複雜度為O(nlogn) 。

三、堆排序

若將堆對應的一維陣列看成是一棵完全二叉樹,則其含義可以闡述為:完全二叉樹中所有非終端結點的值均不大於(或不小於)其左右孩子結點的值。

堆排序的定義為:

    若在輸出堆頂的最小值之後,使得剩餘的n-1個元素的序列又重構成一個堆,則得到 n 個元素中的次小值,如此反覆執行,便能夠得到一個有序序列。

堆排序的執行時間主要消耗在初始建堆和堆重構上,對於記錄較少的檔案並不值得提倡,但對於n較大的檔案來說還是十分有效的。

堆排序的優點:

1)即使是在最壞情況下,其時間複雜度也是O(nlogn)。

2)只需要一個記錄大小的供交換使用的輔助儲存空間。

其Java實現程式碼如下:

/**
 * 堆排序
 * 堆採用順序結構儲存
 * @author Administrator
 *
 */
public class Demo09 {
	/**
	 * 在arr[s...m]中的關鍵字除了arr[s]外均滿足堆的定義
	 * 本函式調整arr[s]關鍵字,使得arr[s...m]成為一個大頂堆。
	 * @param arr
	 * @param s
	 * @param m
	 */
	private static void heapAdjust(int[] arr,int s,int m){
		int rc=arr[s];
		/*
		 * 沿著關鍵字較大的孩子結點向下篩選
		 */
		for(int j=2*s;j<=m;j*=2){
			//j為關鍵字較大的記錄的下標
			if(j<m&&arr[j]<arr[j+1])
				j++;
			if(!(rc<arr[j]))
				break;
			arr[s]=arr[j];
			s=j;
		}
		arr[s]=rc;
	}
	/**
	 * 對順序表進行堆排序
	 * @param arr
	 */
	public static void heapSort(int[] arr){
		/*
		 * 把arr[1...arr.length-1]建成大頂堆
		 */
		for(int i=arr.length/2;i>0;i--)
			heapAdjust(arr, i, arr.length-1);
		for(int i=arr.length-1;i>1;i--){
			int temp=arr[1];
			arr[1]=arr[i];
			arr[i]=temp;
			heapAdjust(arr, 1, i-1);
		}
	}
	public static void main(String[] args) {
		int[] arr=new int[10];
		arr[0]=0;
		arr[1]=15;
		arr[2]=98;
		arr[3]=105;
		arr[4]=45;
		arr[5]=8;
		arr[6]=51;
		arr[7]=18;
		arr[8]=66;
		arr[9]=21;
		heapSort(arr);
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
	}
}