數據結構(24)--排序篇之交換排序

參考書籍:數據結構(C語言版)嚴蔚敏吳偉民編著清華大學出版社

本文中的代碼可從這裏下載:https://github.com/qingyujean/data-structure

1.冒泡排序

1.1基本思想

    小的浮起,大的沉底
具體做法:
第一趟:第1個與第2個比較,大則交換;第2個與第3 比較,大則交換,… 關鍵字最大的記錄交換到最後一個位置上;
第二趟:對前n-1個記錄進行同樣的操作,關鍵字次大 的記錄交換到第n-1個位置上;依次類推,則完成排序。

1.2代碼實現

 

package sort.swampSort;

public class BubbleSort {
	/**
	 * @param args
	 */
	//冒泡排序
	public static void bubbleSort(int[] L){
		for(int i = L.length-1; i > 1; i--){//i控制比較的趟數,比較n-1趟
			for(int j = 1; j < i; j++){
				if(L[j] > L[j+1]){//交換
					L[0] = L[j+1];
					L[j+1] = L[j];
					L[j] = L[0];
				}			
			}
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] test = {0, 25, 56, 49, 78, 11, 65, 41, 36}; //0號單元未使用
		bubbleSort(test);
		for(int i = 1; i <= test.length-1; i++)
			System.out.print(test[i]+" ");
	}

}

運行結果:

 

1.3性能分析

    正序:只需進行一趟排序,在排序過程中進行n-1次關鍵字間的比較,且不移動記錄;時間複雜度爲O(n) 。
    逆序:需要進行n-1趟排序,需要進行n(n-1)/2次比較,並作等數量級的記錄移動。總的時間複雜度爲O(n^2) 。
    起泡排序方法是穩定的。適合於數據較少的情況。

2.快速排序

 

2.1基本思想

 

    背景:起泡排序的過程可見,起泡排序是一個增加有序序列長度的過程,也是一個縮小無序序列長度的過程,每經過一趟起泡,無序序列的長度只縮小 1。試設想:若能在經過一趟排序,使無序序列的長度縮小一半,則必能加快排序的速度。

    基本思想:通過一趟排序將待排序列以樞軸爲標準劃分成兩部分,使其中一部分記錄的關鍵字均比另一部分小,再分別對這兩部分進行快速排序,以達到整個序列有序。通常取第一個記錄的值爲基準值或樞軸

    具體做法:附設兩個指針low和high,初值分別指向第一個記錄和最後一個記錄,設樞軸爲 key;
    (1)從high 所指位置起向前搜索,找到第一個不大於基準值的記錄與樞軸記錄相互交換;
    (2)從low 所指位置起向後搜索,找到第一個不小於基準值的記錄與樞軸記錄相互交換。
    (3)重複這兩步直至low=high爲止。

2.2代碼實現

 

package sort.swampSort;

public class QuickSort {

	/**
	 * @param args
	 */
	//交換順序表L的字表L[low...high]的記錄,樞軸記錄到爲,並返回樞軸應該所在的位置
	//此時,樞軸前面的記錄均小於樞軸,樞軸後面的記錄均大於樞軸
	//是一趟快排
	public static int partion(int[] L, int low, int high){
		L[0] = L[low];//L[0]暫存樞軸,字表中的第一個元素一般默認爲是樞軸
		while(low < high){
			while(low < high && L[0] <= L[high])
				high--;
			//此時L[high]>L[0]
			L[low++] = L[high];
			while(low < high && L[0] >= L[low])
				low++;
			//此時L[low]>L[0]
			L[high--] = L[low];
		}
		//循環結束時,一定有low==high
		L[low] = L[0];
		return low;
	}
	
	//遞歸形似的快速排序
	public static void quickSort(int[] L, int low, int high){
		//對順序表L的子序列L[low...high]做快速排序
		if(low < high){
			int m = partion(L, low, high);
			quickSort(L, low, m-1);
			quickSort(L, m+1, high);
		}
		//low==high時,說明子序列中僅有一個元素了,顯然已經有序,應作爲每一層遞歸的結束
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] test = {0, 46, 55, 13, 42, 94, 5, 17, 70}; //0號單元未使用
		quickSort(test, 1, test.length-1);
		for(int i = 1; i <= test.length-1; i++)
			System.out.print(test[i]+" ");
	}
}

運行結果:

 


2.3性能分析

    最好的情形(左、右子區間的長度大致相等),快速排序的最好時間複雜度應爲O(nlog2n)
    最壞的情形(每次能劃分成兩個子區間,但其中一個是空),快速排序的最壞時間複雜度爲O(n^2),退化成冒泡排序
    對n較大的情況,它是平均速度最快的排序算法,但當n很小時,此方法往往比其他簡單排序方法還要慢。
    快速排序是不穩定的。

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