1、基本思想算法
每次從待排記錄中選出最小值放在有序記錄的末尾。等每個待排元素均被選出後,整個記錄排序就完成了。dom
2、實現步驟工具
這裏採用雙向選擇排序,每次從待排記錄中選出最大值和最小值,最大值和待排記錄的最後一位交換位置,最小值和待排記錄的第一位交換位置。測試
注意,交換位置分以下狀況:spa
1)最大值在最左邊,最小值在最右邊。直接將最大值最小值相互交換便可。3d
2)最大值在最左邊,最小值在中間。必須先將最大值與最後一位交換,再將最小值與第一位交換。不然會出錯,不信就試試。code
3)最大值在中間,最小值在中間。隨意誰先交換都行。blog
4)最小值在最右邊,最大值在中間。必須先將最小值與第一位交換,再將最大值與最後一位交換。排序
5)最小值在最右邊,最大值在最左邊。不用交換。get
對於上述5種狀況,其實能夠簡化成以下狀況來作。
1、若是max在最左邊,
若是min在最右邊,二者直接交換
不然,先交換max,再交換min
2、其餘狀況一概先交換min,再交換max。
max在最左,min在最右這種狀況,因爲兩次交換,等同於沒交換,因此不會出現錯誤。
3、實現代碼
測試工具類 點擊這裏
package sort; import sort.util.*; /* 選擇排序思路: 選擇待排記錄中最小值,放在左邊 雙向選擇,一次遍歷中選出最大值放在右邊,選出最小值放在左邊 時間複雜度:O(n2) 空間複雜度:O(1) 穩定性: 穩定 */ public class SelectSort implements ISort{ public void sort(int[] a) { int n = a.length; for(int i = 0; i < n / 2; i++) { int maxId = i; int minId = i; for(int j = i; j <= n - i - 1; j++) { if(a[j] > a[maxId]) {maxId = j;} if(a[j] < a[minId]) {minId = j;} } //根據maxId的位置走不一樣的交換順序 int t = 0; if(maxId == i){ if(minId == n - 1 - i) { t = a[maxId]; a[maxId] = a[minId]; a[minId] = t; //max和min位於相反的位置上,直接將其交換 }else{ t = a[maxId]; a[maxId] = a[n-1-i]; a[n-1-i] = t; //max位於最左,先交換max t = a[minId]; a[minId] = a[i]; a[i] = t; //再交換min } }else{ t = a[minId]; a[minId] = a[i]; a[i] = t; //min位於最右和其餘狀況,先交換min t = a[maxId]; a[maxId] = a[n-1-i]; a[n-1-i] = t; } } } public static void main(String[] args) { int[] array = RandomArrayGenerator.getRandomArray(100 , 30); SortTestHelper.test(new SelectSort() , array); } }
測試結果:
4、總結分析
時間複雜度:O(n2)
空間複雜度:O(1)
選擇排序是一種比較直觀易懂的排序算法,時間複雜度不理想,但幾乎不佔空間。下篇將展現選擇排序的改進算法 ----- 堆排序。