詳細描述
選擇排序的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾,以此類推,直到全部待排序的資料元素的個數為零。
選擇排序詳細的執行步驟如下:
- 初始狀態:無序區為 R[1..n],有序區為空;
- 第 i 趟排序 (i=1,2,3…n-1) 開始時,當前有序區和無序區分別為 R[1...i-1] 和 R(i...n)。該趟排序從當前無序區中選出關鍵字最小的記錄 R[k],將它與無序區的第 1 個記錄 R 交換,使 R[1...i] 和 R[i+1...n) 分別變為記錄個數增加 1 個的新有序區和記錄個數減少 1 個的新無序區;
- 經過 n-1 趟,無序序列就有序化了。
演算法圖解
問題解疑
為什麼選擇排序是不穩定的?
雖然原理上存在有序區和無序區的區分,但是選擇排序演算法為了提高空間的使用率,使用的是原地交換方式。
與氣泡排序兩兩比較交換不同,選擇排序演算法是最小的元素與固定位置的元素進行交換,當這個固定位置的元素被交換到另一個位置之後,也就有可能導致相等的數字次序變化。
選擇排序的時間複雜度是多少?
無論原序列是有序還是無序,選擇排序都需要對序列做完整的遍歷,即最好情況時間複雜度和最壞情況時間複雜度都是 \(O(n^2)\);平均時間複雜度是 \(O(n^2)\)。
程式碼實現
package cn.fatedeity.sort;
/**
* 選擇排序演算法
*/
public class SelectionSort {
private static void swap(int[] numbers, int src, int target) {
int temp = numbers[src];
numbers[src] = numbers[target];
numbers[target] = temp;
}
public static int[] sort(int[] numbers) {
for (int i = 0; i < numbers.length - 1; i++) {
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[i] <= numbers[j]) {
continue;
}
swap(numbers, i, j);
}
}
return numbers;
}
}