經典排序算法——選擇排序


選擇排序的原理

選擇排序的原理是首先取第一個數字作為數組中的最小者minValue(以升序排序為例),依次跟后續數字進行比較,如果發現有比minValue更小的數字,記錄該數字的下標,並將該數字的值賦給minValue,直到遍歷完數組的最后一個數字。然后根據記錄的實際最小值的下標,跟第一個數字進行交換。

第一趟比較執行完后就找到了數組中最小者,然后再從下一個數字開始,重復執行前面的步驟,直到倒數第二個數字比較完為止(最后數字無需比較即為最大數字)

 圖解選擇排序過程

假設要排列的數字為 3 1 4 2 ,當進行第一趟排序時,如下圖所示(其中i表示數組的下標)

第一趟排序后,數組中最小的數字1已找到並放置在第0位置。下面看第二趟比較,如下圖所示。

第二趟比較從第二個數開始,將minIndex設置為1,並將minValue設置為4。並依次跟后面的數比較,發現3<4,將minIndex和minValue修改為對應值。繼續向后比較發現2<3,將minIndex和minValue修改為對應值。第二趟遍歷結束,將第1位置的值設置為minIndex對應的值2,並將minIndex值設置為4。第二趟比較結束。繼續執行第三趟排序(雖然我們看到現在數組已經有序,但程序不知道)。第三趟比較如下圖所示

第三趟比較時,將minIndex設置為2,minValue設置為3。依次向后比較,4>3不改變minIndex和minValue。遍歷結束,無需進行交換(通過趟數值與minIndex值是否相等來判斷是否需要交換)

代碼實現

 1 public static void sort(int array[]){
 2         //第一個for循環表示要進行length-1次選擇
 3         for (int i = 0; i < array.length - 1; i++) {
 4             int minIndex = i;
 5             int minValue = array[minIndex];
 6             for (int j= i+1; j<array.length; j++){
 7                 if(minValue > array[j]){
 8                     minIndex = j;
 9                     minValue = array[j];
10                 }
11             }
12             //執行完一輪選擇后進行交換(如果最小值下標有改變才進行交換)
13             if(minIndex != i){
14                 array[minIndex] = array[i];
15                 array[i] = minValue;
16             }
17         }
18     }

代碼分析

1)第一層for循環確定比較趟數,通過我們的分析,比較n-1趟即可(n為數組長度)

2)第二層for循環用於遍歷所選擇的最小值后續數字,比較是否有小於所選擇的最小值,如果有,則修改minIndex和minValue

3)if提交判斷,用於判定minIndex是否被修改過,如果沒有修改過,則無需交換(否則自己與自己交換,無意義)

時間復雜度

選擇排序有兩層for循環,所示時間復雜度為T(n)=O^2

測試執行時間

與上一篇冒泡排序相同,依然生成10萬個數字進行排序。代碼如下

1 public static void main(String []args){
2         int array[] = new int[100000];
3         for (int i = 0; i < 100000; i++) {
4             array[i] = (int) (Math.random()*1000000);
5         }
6         long begin = System.currentTimeMillis();
7         sort(array);
8         System.out.println("總耗時="+(System.currentTimeMillis()-begin));
9     }

執行結果(單位為毫秒)

 

可以看出,在我的機器上使用選擇排序對10萬個數字的數組進行排序,大概需要3秒多的時間,比冒泡排序的17秒快了很多。下一篇我將講解插入排序的過程,耗時會不會更小呢?一起期待!!!

總結

選擇排序需要注意兩點,一是比較的趟數,有n個數,比較n-1即可。二是每趟比較,都認為當前數為最小(或最大)值,然后依次跟后面數字比較,如果發現有比我們假設的最小值更小,則改變成新的下標和新的最小值繼續向后比較,直到遍歷完所有數字。如果假設的最小值下標有修改則進行交換。

 


免責聲明!

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



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