詳解選擇排序算法


基本思想

選擇排序的思想是:
給定一個數組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 ];
則其初始狀態為:
初始狀態

定義兩個變量minIndexmin,分別表示最小值元素的索引,和最小值元素的值。
先假定最小值元素為循環開始的第一個元素。
第一次循環將minIndexmin分別賦值為 0300
循環變量為當前元素的下一個元素的索引。
由圖來演示算法過程:
黃色表示當前循環需要遍歷的元素。

第一趟排序

第一趟排序狀態1

此時 50 < min當前值300,將minIndex賦值為1,將min賦值為50;

第一趟排序狀態2
循環變量向后移動。

第一趟排序狀態3

此時 120 > min當前值50,循環變量直接向后移動;

第一趟排序狀態4

此時 110 > min當前值50,循環變量無法向后移動,當前循環結束。

minIndex不等於循環開始前的首元素的索引0,發生交換。

第一趟排序狀態5

第二趟排序

第二趟排序狀態1

此時 120 > min當前值100,循環變量直接向后移動;

第二趟排序狀態2

此時 120 > min當前值110,循環變量向后移動則會發生越界,當前循環結束。

minIndex等於循環開始前的首元素的索引1,不發生交換。

第三趟排序

第三趟排序狀態1

此時 110 < min當前值120,將minIndex賦值為3,將min賦值為110;

第三趟排序狀態2

循環變量再向后移動則會發生越界,當前循環結束。

minIndex不等於循環開始前的首元素的索引2,發生交換。

第三趟排序狀態3

因為前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隨筆
微信公眾號:code隨筆


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM