---
# System prepended metadata

title: 選擇排序法(Selection sort)

---

# 選擇排序法(Selection sort)

假設我們要使用選擇排序法進行陣列元素由小到大的排序，我們需要從未排序的元素中找到最小值將之與前面的值做交換，下面我直接舉例說明可能會比較容易理解。

## 舉例說明

假設使用選擇排序法將陣列中的值由小到大排序。

初始陣列為：[8,3,2,1,7,4,6,5]

那麼第一次排序時會由左至右在陣列中找到最小的值，並將之與第一個位置的值做交換，因此第一輪結束後的陣列為：[1,3,2,8,7,4,6,5]。

完整的排序結果如下圖所示：

![](https://i.imgur.com/6Djt5jk.png)

### 說明
1. 選擇排序一共有 `陣列大小-1` 輪排序。
2. 每一輪排序又是一個循環。

### 循環的規則
1. 先假定當前這個數是最小數，然後和後面的每個數進行比較。
2. 如果發現有比當前數更小的數，就重新確定最小數，並得到索引值。
3. 當遍歷到陣列的最後時，就得到本輪的最小值和對應的索引。
4. 將目前的數與最小值交換。

## 程式碼實現
```java=
import java.util.Arrays;

public class SelectionSort {
    public static void main(String[] args) {

        int arr[] = {8,3,2,1,7,4,6,5};
        int min; //紀錄本輪最小值
        int index = 0; //紀錄最小值位置索引

        for(int i = 0; i < arr.length - 1; i++) { //總共比 陣列大小-1 輪
            min = arr[i]; //將當前數設為最小
            for(int j = i+1; j <= arr.length - 1; j++) {//對剩下的元素進行比較
                if(arr[j] < min) { //若有比當前數還小的元素
                    min = arr[j]; //紀錄最小值
                    index = j; //紀錄最小值索引
                }
            }
            if(index != i) {
                arr[index] = arr[i]; //將當前值放到最小值位置完成交換
                arr[i] = min; //把最小值與當前值做交換
            }
            System.out.println("第"+(i+1)+" 輪結果為: "+Arrays.toString(arr));
        }
    }
}
```

output
```java=
第1 輪結果為: [1, 3, 2, 8, 7, 4, 6, 5]
第2 輪結果為: [1, 2, 3, 8, 7, 4, 6, 5]
第3 輪結果為: [1, 2, 3, 8, 7, 4, 6, 5]
第4 輪結果為: [1, 2, 3, 4, 7, 8, 6, 5]
第5 輪結果為: [1, 2, 3, 4, 5, 8, 6, 7]
第6 輪結果為: [1, 2, 3, 4, 5, 6, 8, 7]
第7 輪結果為: [1, 2, 3, 4, 5, 6, 7, 8]
```

## 速度測試

```java=
public static void main(String[] args) {
    // int arr[] = {8,3,2,1,7,4,6,5};
    int arr[] = new int[80000];
    for(int i = 0; i < 80000; i++) {
        arr[i] = (int)(Math.random() * 80000);
    }
    Instant startTime = Instant.now();
    selectionSort(arr);
    Instant endTime = Instant.now();
    System.out.println("共耗時：" + Duration.between(startTime, endTime).toMillis() + " 毫秒");
}
```

output
```java=
共耗時：642 毫秒
共耗時：630 毫秒
共耗時：632 毫秒
共耗時：632 毫秒
```

八萬筆隨機數陣列做選擇排序法在我的電腦上跑僅需 634 ms，比泡沫排序法的 7 秒還快很多，因此我們可以得出結論：同樣大小的資料進行泡沫和選擇排序，選擇排序的速度會比泡沫排序來的快。

其實光是看程式碼就能知道，因為泡沫排序法兩個for迴圈都是由0開始，而選擇排序法第二層for迴圈是從 i+1 開始，所以需要比對的資料沒有那麼多，速度會比較快。

## 時間複雜度
假設今天要對一陣列使用選擇排序法由小到大排序。

### 最佳：O(n^2^)

### 平均：O(n^2^)

### 最差：O(n^2^)

無論資料順序如何，都會執行兩個迴圈。