選擇排序演算法,C語言選擇排序演算法詳解

2020-07-16 10:04:20
選擇排序是一種簡單直觀的排序演算法。它與氣泡排序很相似,都是比較 n-1 輪,每輪都是比較 n–1–i 次,每輪找出一個最大值或最小值。

只不過,氣泡排序是將每輪找出的最值放到最右邊,而選擇排序是將每輪找出的最值放到最左邊。並且在演算法上,氣泡排序是將相鄰的數進行逐個比較,以從小到大排序為例,只要前面的比後面的大,就互換這兩個數,直到最後將最大的數“浮”到最右邊,如此依次迴圈。而選擇排序是先儲存第一個元素的下標,然後後面所有的數依次與第一個元素相比,如果遇到更小的,則記錄更小的那個數的下標,然後後面所有的數都依次與那個更小的數比較,直到最後將最小的數的下標找出來,然後再將這個數放到最左邊,即與下標為 0 的數互換。如果最小的數的下標就是 0 那麼就不用互換。

所以,選擇排序演算法是先判斷最小的數的下標是不是 0,如果不是則說明最小的數不是第一個元素,則將這個數與第一個元素互換位置,這樣一輪下來最小的那個數就被找到並放到了最左邊。

在第二輪同樣先儲存新序列第二個元素的下標,後面所有的數依次與第二個元素相比較,如果遇到更小的則記錄更小的那個數的下標,然後後面所有的數都依次與那個更小的數比較,直到最後又找到一個最小的,此時這個最小的在整個序列中是“第二小”。然後再判斷這個數的下標是否等於 1,如果不等於 1 說明“第二小”的那個數不是第二個元素,則將這個數與第二個元素互換位置,這樣第二輪下來就找到了“第二小”的那個數,並將它放到了第二個位置。如此迴圈,直到整個序列實現從小到大排序。

如果是從大到小排序,那麼就記錄大的那個數的下標,每一輪找出一個最大的數放到左邊。

從上面的分析可以看出,選擇排序和氣泡排序的另一個不同點是,氣泡排序只要遇到前面比後面大的就互換,而選擇排序是比較一輪才互換一次,而且如果本輪中最小的就是最左邊那個數則不用互換。所以從這個角度看,選擇排序比氣泡排序的效率要高。而且通過上面對選擇排序的分析發現,從邏輯上講,與氣泡排序相比,選擇排序更符合人的思維。

下面來寫一個程式,用選擇排序實現一個序列的從小到大排序:
# include <stdio.h>
int main(void)
{
    int i, j;  //迴圈變數
    int MinIndex;  //儲存最小的值的下標
    int buf;  //互換資料時的臨時變數
    int a[] = {5, 5, 3, 7, 4, 2, 5, 4, 9, 1, 8, 6};
    int n = sizeof(a) / sizeof(a[0]);  //存放陣列a中元素的個數
    for (i=0; i<n-1; ++i)  //n個數比較n-1輪
    {
        MinIndex = i;
        for (j=i+1; j<n; ++j)  //每輪比較n-1-i次, 找本輪最小數的下標
        {
            if (a[MinIndex] > a[j])
            {
                MinIndex = j;  //儲存小的數的下標
            }
        }
        if (MinIndex != i)  /*找到最小數之後如果它的下標不是i則說明它不在最左邊, 則互換位置*/
        {
            buf = a[MinIndex];
            a[MinIndex] = a[i];
            a[i] = buf;
        }
    }
    printf("最終排序結果為:n");
    for (i=0; i<12; ++i)
    {
        printf("%d ", a[i]);
    }
    printf("n");
    return 0;
}
輸出結果是:
最終排序結果為:
1 2 3 4 4 5 5 5 6 7 8 9

通過程式可以看出,雖然選擇排序比氣泡排序的效率高,邏輯上也更符合人的思維,但是程式相對更複雜,氣泡排序比選擇排序在邏輯上要清晰一點,也稍微簡單一點。