1. 程式人生 > >《資料結構與演算法》之排序演算法(氣泡排序、選擇排序)

《資料結構與演算法》之排序演算法(氣泡排序、選擇排序)

排序(Sorting) 是計算機程式設計中的一種重要操作,它的功能是將一個數據元素(或記錄)的任意序列,重新排列成一個關鍵字有序的序列。

排序演算法分類

一、非線性時間比較類排序

1、交換排序(氣泡排序、快速排序)

2、插入排序(簡單插入排序、布林排序)

3、選擇排序(簡單選擇排序、堆排序)

4、歸併排序(二路歸併排序、多路歸併排序)

二、線性時間非比較類排序

1、計數排序

2、桶排序

3、基數排序

各排序演算法的比較:

排序方法 時間複雜度(平均) 時間複雜度(最壞) 時間複雜度(最好) 空間複雜度 穩定性
插入排序 O(n^2 O(n^2 O(n O(1) 穩定
希爾排序 O(n^{1.3} O(n^2 O(n O(1) 不穩定
選擇排序 O(n^2 O(n^2 O(n^2 O(1) 不穩定
堆排序 O(nlog_{2}n O(nlog_{2}n O(nlog_{2}n O(1) 不穩定
氣泡排序 O(n^2 O(n^2 O(n
O(1) 穩定
快速排序 O(nlog_{2}n O(n^2 O(nlog_{2}n O(nlog_{2}n 不穩定
歸併排序 O(nlog_{2}n O(nlog_{2}n O(nlog_{2}n O(n) 穩定
 
計數排序 O(n+k) O(n+k) O(n+k) O(n+k) 穩定
桶排序 O(n+k) O(n^2 O(n) O(n+k) 穩定
基數排序 O(n*k) O(n*k) O(n*k) O(n+k) 穩定

其中,

穩定:如果a原本在b前面,而a=b,排序之後a仍然在b的前面。

不穩定:如果a原本在b的前面,而a=b,排序之後 a 可能會出現在 b 的後面。

時間複雜度:對排序資料的總的操作次數。反映當n變化時,操作次數呈現什麼規律。

空間複雜度:是指演算法在計算機內執行時所需儲存空間的度量,它也是資料規模n的函式。

 排序演算法實現:

1、氣泡排序

氣泡排序的運作規律如下:

(1)比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

(2)對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數(也就是第一波冒泡完成)。

(3)針對所有的元素重複以上的步驟,除了最後一個。

(4)持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。

public class BubbleSort {
    
    //氣泡排序演算法
	public static int[] sort(int[] array){
		//這裡for迴圈表示總共需要比較多少輪
		for(int i = 1 ; i < array.length; i++){			
			//j的範圍很關鍵,這個範圍是在逐步縮小的,因為每輪比較都會將最大的放在右邊
			for(int j = 0 ; j < array.length-i ; j++){
				if(array[j]>array[j+1]){
					int temp = array[j];
					array[j] = array[j+1];
					array[j+1] = temp;
				}
			}
		}
		return array;
	}
	
	//遍歷顯示陣列
	public static void display(int[] array){
		for(int i = 0 ; i < array.length ; i++){
			System.out.print(array[i]+" ");
		}
		System.out.println();
	}
	
	public static void main(String[] args) {
		int[] array = {4,2,8,9,5,7,6,1,3};
		System.out.println("未排序陣列順序為:");
		display(array);
		array = sort(array);
		System.out.println("經過氣泡排序後的陣列順序為:");
		display(array);
	}

}

2、選擇排序

選擇排序(Selection-sort)的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

public class SelectionSort {

	public static void main(String[] args) {
		int[] array = { 4, 2, 8, 9, 5, 7, 6, 1, 3 };
		System.out.println("未排序陣列順序為:");
		display(array);
		array = selectionSort(array);
		System.out.println("經過選擇排序後的陣列順序為:");
		display(array);
	}

	// 選擇排序方法
	private static int[] selectionSort(int[] arr) {
		int len = arr.length;
		int minIndex, temp;
		for (int i = 0; i < len - 1; i++) {
			minIndex = i;
			for (int j = i + 1; j < len; j++) {
				if (arr[j] < arr[minIndex]) { // 尋找最小的數
					minIndex = j; // 將最小數的索引儲存
				}
			}
			temp = arr[i];
			arr[i] = arr[minIndex];
			arr[minIndex] = temp;
		}
		return arr;
	}

	// 遍歷顯示陣列
	public static void display(int[] array) {
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i] + " ");
		}
		System.out.println();
	}
}