基本思想
選擇排序的思想是:
給定一個數組arr,其長度為n;
第一次從 arr[0] 到 arr[n-1] 中選取一個最值(按照需求,可以是最大值,可以是最小值,下同)與arr[0]進行交換;
第二次從arr[1] 到 arr[n-1] 中選取一個最值與arr[1]進行交換;
以此類推,直到arr[n-2]到arr[n-1]中選出最值交換后即完成排序。(只剩下一個元素,前面的都是比它小(或者大)的)。
例子
給定數組 arr 為 [ 300, 50 , 120 , 110 ];
則其初始狀態為:
定義兩個變量minIndex、min,分別表示最小值元素的索引,和最小值元素的值。
先假定最小值元素為循環開始的第一個元素。
第一次循環將minIndex、min分別賦值為 0和300。
循環變量為當前元素的下一個元素的索引。
由圖來演示算法過程:
黃色表示當前循環需要遍歷的元素。
第一趟排序
此時 50 < min當前值300,將minIndex賦值為1,將min賦值為50;
循環變量向后移動。
此時 120 > min當前值50,循環變量直接向后移動;
此時 110 > min當前值50,循環變量無法向后移動,當前循環結束。
minIndex不等於循環開始前的首元素的索引0,發生交換。
第二趟排序
此時 120 > min當前值100,循環變量直接向后移動;
此時 120 > min當前值110,循環變量向后移動則會發生越界,當前循環結束。
minIndex等於循環開始前的首元素的索引1,不發生交換。
第三趟排序
此時 110 < min當前值120,將minIndex賦值為3,將min賦值為110;
循環變量再向后移動則會發生越界,當前循環結束。
minIndex不等於循環開始前的首元素的索引2,發生交換。
因為前n-1個元素均排序完畢,所以原數組排序完畢。
我們由例子可知:
選擇排序的趟數為數組長度-1
代碼
由上面的講解知道要寫成雙重循環,最終代碼如下:
import java.util.Arrays;
public class Solution {
public static void main(String[] args) {
int [] arr = new int[]{300,50,120,110};
System.out.println("排序前的數組" + Arrays.toString(arr));
selectSort(arr);
System.out.println("排序前的數組" + Arrays.toString(arr));
}
public static void selectSort(int[] arr){
int minIndex;//最小值元素索引
int min;//最小值元素
for (int i = 0; i < arr.length - 1; i++) {
minIndex = i;
min = arr[i];
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]) {
min = arr[j];
minIndex = j;
}
}
//交換
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
}
}
}
時間復雜度
比較次數與關鍵字的初始狀態無關,總的比較次數N=(n-1)+(n-2)+...+1= $\frac{n(n-1)}{2}$。為 $O(n^2)$。
穩定性
選擇排序是不穩定的排序算法。
舉個例子來說明:
序列 6 9 6 3 10
在第一趟排序時第一個6會和3交換位置,那么原序列中兩個6的相對前后順序就被破壞了。
所以選擇排序是一個不穩定的排序算法。
歡迎關注
歡迎大家的關注
掃描下方的二維碼或者微信搜一搜即可關注我的微信公眾號:code隨筆