簡單選擇排序介紹
簡單選擇排序法就是通過n-i次關鍵字比較,找到最小的關鍵字下標,最後在替換n-i下標和最小下標的值。
簡單排序的思想和冒泡排序的思想的區別是冒泡排序是相鄰關鍵字兩兩比較,如果小,則直接替換,可能在一輪循環會進行多次值交換。而簡單選擇排序法是一輪循環找到最小關鍵字下標,最後進行最多一次替換。
簡單選擇排序算法
public static void simpleSelectionSort(Integer[] arr) {
for (int i = 0; i < arr.length; i++) {
int min = i;//初始最小關鍵字下標爲i
for (int j = i + 1; j < arr.length; j++) {
if (arr[min] > arr[j]) { // 如果前一個元素比後一個元素大,則替換位置
min = j;
}
}
if (min != i) {//如果一輪比較下來,最小下標和當前i下標不一致,則替換值
Integer temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
}
假設需要對關鍵字序列{9,3,8,2,7,4,6,1,5}使用簡單選擇排序,如下圖:
如上面圖的流程所示,當i=0,j=1,min=0時,進行比較[min]>[j],所以min=1。當j=3時,[min]>[j],所以min=3。當j=7時,[min]>[j],所以min=7。最後替換min下標和i下標的值,也就是把找到的最小關鍵字和第一位替換。同理,然後進行下一個最小關鍵字的輪詢比較替換。
時間複雜度
最好的情況和最差情況比較次數相同。第i趟排序需要進行n-i次比較,總共需要比較次。
對於交換來說,最好情況,不需要交換。最差情況也就是逆序時,需要交換n-1次。
最終的時間複雜度爲O()。
和冒泡排序的性能比較
前面有說冒泡排序一輪比較大小可能會多次大小值替換,而簡單選擇排序每次輪詢只需要進行最多一次值替換。接下來我們就來看下序列長度爲10萬個隨機數,分別用冒泡和簡單選擇兩種算法執行時間需要多久。
public static void main(String[] args) {
Integer[] arrs = new Integer[100000];
Random random = new Random();
for (int i = 0; i < arrs.length; i++) {
arrs[i]=random.nextInt(arrs.length);
}
Integer[] newArrays = Arrays.copyOf(arrs, arrs.length);
long start = System.currentTimeMillis();
simpleSelectionSort(newArrays);
long end = System.currentTimeMillis();
System.out.println("簡單選擇排序執行時間:"+(end-start)+"ms");
newArrays = Arrays.copyOf(arrs, arrs.length);
start = System.currentTimeMillis();
bubbleSort(newArrays);
end = System.currentTimeMillis();
System.out.println("冒泡排序執行時間:"+(end-start)+"ms");
}
public static void simpleSelectionSort(Integer[] arr) {
for (int i = 0; i < arr.length; i++) {
int min = i;//初始最小關鍵字下標爲i
for (int j = i + 1; j < arr.length; j++) {
if (arr[min] > arr[j]) { // 如果前一個元素比後一個元素大,則替換min值
min = j;
}
}
if (min != i) {//如果一輪比較下來,最小下標和當前i下標不一致,則替換值
Integer temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
}
public static void bubbleSort(Integer[] arr) {
boolean flag = true; //flag標記是否需要繼續循環
for (int i = 0; i < arr.length && flag; i++) {//每一輪循環進行flag判斷
flag = false;
for (int j = arr.length - 1; j > i; j--) {
if (arr[j - 1] > arr[j]) { // 如果前一個元素比後一個元素大,則替換位置
Integer temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
flag = true; //有數據交換則將flag置爲true
}
}
}
}
最終得到的結果如下:
簡單選擇排序執行時間:7455ms
冒泡排序執行時間:28337ms
我們發現當數量比較大的無序序列進行排序時,簡單選擇排序相較於冒泡排序省去了大量的值替換操作,所以耗時比冒泡要少的多。所以,我們得出的結論是簡單選擇排序比冒泡排序的性能要優。