1. 選擇排序思想
選擇排序,就是通過選擇,將元素放到合適的位置上。那麼,如何進行選擇呢?
舉個例子,大家在買東西時,一定會貨比三家吧。我們肯定是希望花最少的錢,買最優的貨,這種比較選擇,就是選擇排序的思想。
我現在要在某寶買三頂假髮,在購物車添加了五個不同的店家商品(假定我只在一家店只買一件商品)。首先,我會以一家的價錢作爲標準,然後和其他四家店的價格比較。比完之後我會選出一件最便宜的付款,然後再剩下的四家中再次選出最便宜的進行比較購買。這就是選擇排序的選擇。
2. 選擇排序詳解
對序列【4 , 6 , 8 , 7 , 6 , 2 , 9 , 1】遞增排序
-
我們讓min作爲進行選擇探測的指針
-
對原數據而言,假定第一個索引處的元素是最小值,即當前
min = 4
; -
第一趟排序:min依次和之後索引處的數進行比較,當它到索引5所指向的數
2
時,發現此索引處的數比自己小,於是讓自己指向當前元素,即min = 2
;然後min
繼續向後探測,發現末尾索引處元素2
比自己還小,繼續更換,min = 1
;
- 此時,遍歷完了序列,min發現自己等於
1
時是最小的。於是和當初假裝自己是最小的4
進行交換位置 - 交換完之後,min後移一位,然後又假裝此時自己指向的是最小的元素,第二趟選擇排序開始
- 以此類推繼續排序。倘若比較完後·
min
位置的元素是最小值,那就無需交換,不動即可
- 直到剩餘最後一個元素時,min也不用假裝自己指向的最小元素了,這次是真的了。只剩一個了,一定是最大的了,就不用管了。到此,選擇排序完成!
【動圖詳解】
選擇排序就是通過改變——指向最小元素索引的位置來尋找每趟最小的數,每趟遍歷交換指針min指向的值,來比較確定出每趟的最小元素,之後交換元素位置
3. 代碼實現
外層循環完成了數據交換,內層循環完成了數據比較
public static void selectSort(int[] arr) {
//參與選擇排序的元素:只剩一個元素時不用選擇,到倒數第二個元素截止
for (int i = 0; i < arr.length - 1; i++) {
//假定本次遍歷最小值所在的索引是i,默認第一個
int minIndex = i;
//讓當前最小元素與它後面的元素依次進行比較
for (int j = i + 1; j < arr.length; j++) {
if(arr[minIndex] > arr[j]) {
//交換最小值所在的索引
minIndex = j;
}
}
//將最小元素所在索引minIndex處的值與i索引的值交換
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
測試
歸併排序後爲:[1, 2, 4, 6, 6, 7, 8, 10]
4. 複雜度分析
【時間複雜度】
選擇排序使用了雙層for
循環,其中外層循環完成了數據交換,內層循環完成了數據比較,數據
交換次數和數據比較次數:
數據交換次數:N-1
數據比較次數:(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2
時間複雜度:N^2 / 2 - N / 2 + (N-1) = N ^ 2/2 + N/2-1;
根據大O推導法則,保留最高階項,去除常數因子,時間複雜度爲O(N^2)
【空間複雜度】O(1)
《被排序算法吊打系列彙總》