1. 程式人生 > >【演算法】插入排序/氣泡排序/選擇排序

【演算法】插入排序/氣泡排序/選擇排序

插入排序

插入排序的思想為:從陣列的第二個元素開始遍歷整個陣列。針對每個元素,依次將其前面的所有元素和他進行比較,大於它的元素均向後移動,最後將該元素插入。

插入排序是一種穩定的排序演算法。
時間複雜度T(n)=O(n^2)

最好情況下已排好序,T(n)=O(n)

private void swap(int[] a, int i, int j) {
		int temp = a[j];
		a[j] = a[i];
		a[i] = temp;
	}
插入排序的關鍵程式碼
private void insertSort(int[] a) {
		for (int i = 1; i < a.length; i++) {
			int j = i - 1;
			int tmp = a[i];
			while (j >= 0 && a[j] > tmp) { // 穩定的排序,注意順序
				a[j + 1] = a[j];
				j--;
			}
			a[j+1] = tmp;
		}
	}

氣泡排序

氣泡排序的思想為:從第一個元素開始相鄰的兩個元素兩兩比較,按照小數在上大數在下的規則交換,一趟下去大數沉底。
再從第一個元素開始兩兩比較相鄰兩個元素,直到倒數第二個元素
....
氣泡排序也是穩定的排序演算法
氣泡排序的複雜度均為T(n)=O(n^2)

插入排序的關鍵程式碼

public void bubbleSorts(int[] a) {
		/*boolean flag = true;*/
		for (int i = 0; i < a.length - 1 /*&& flag*/; i++) {
			/*flag = false;*/
			for (int j = 0; j < a.length - 1 - i; j++) {
				if (a[j] >= a[j + 1]) {
					swap(a, j, j + 1);
					/*flag = true;*/
				}
			}
		}
	}
註釋是對氣泡排序的改進,當沒有呼叫swap函式表明已經排好序了。這樣可以在最好情況下達到時間複雜度為T(n)=O(n)

選擇排序

從所有序列中先找到最小的,然後放到第一個位置,之後再看剩餘元素中最小的,放到第二個位置……以此類推
選擇排序是不穩定的排序演算法,比如[3,3,1]第一次交換時第一個三就會跑到第二個3後面去。

選擇排序的複雜度均為T(n)=O(n^2)

選擇排序的關鍵程式碼

public void selectSort(int a[]) {
		for(int i = 0; i < a.length - 1; i++){
			// 找到從i開始的最小數
			int minIndex = i;
			for (int j = i + 1; j < a.length; j++) {
				if (a[j] < a[minIndex]) {
					minIndex = j;
				}
			}
			swap(a, i, minIndex);
		}
	}
穩定性指具有相同值得元素在輸出陣列中的相對次序保持和輸入陣列一致。穩定性是排序演算法的一個重要指標,基數排序就要用到穩定的排序演算法作為其子過程。
可能這樣的概念解釋還不是很清晰。舉個例子,我們在實際應用中不會僅僅是比較數字這麼簡單,可能是比較一個物件,一個物件有很多屬性。比如兩個學生的成績包含語文和數學,A[80,90],B[80,85],在對語文成績排序時要保證A在B前,因為對語文成績來說A和B是一樣,但一個物件還包含數學成績,不能再對語文成績排序的時候打亂了數學成績的順序。