1. 程式人生 > 實用技巧 >陣列排序-選擇排序(SelectSort)

陣列排序-選擇排序(SelectSort)


介紹:

選擇排序是一種簡單直觀的排序演算法。它的工作原理是每一次從待排序的資料元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的資料元素排完。選擇排序是不穩定的排序方法(如:序列[5,5,3]第一次就將第一個[5]與[3]交換,導致第一個5挪動到第二個5後面)。


思想:

n個記錄的檔案的直接選擇排序可經過n-1趟直接選擇排序得到有序結果:
a.初始狀態:無序區為R[1..n],有序區為空。
b.第1躺排序
在無序區R[1..n]中選出關鍵字最小的記錄R[k],將它與無序區的第1個記錄R[1]交換,使R[1..1]和R[2..n]分別變為記錄個數增加1個的新有序區和記錄個數減少1個的新無序區。
c.第i趟排序
第i趟排序開始時,當前有序區和無序區分別為R[1..i-1]和R[i..n]。該趟排序從當前無序區中選出關鍵字最小的記錄R[k],將它與無序區的第1個記錄R交換,使R[1..i]和R分別變為記錄個數增加1個的新有序區和記錄個數減少1個的新無序區。


示例:

package com.cnblogs.lxj;

/**
 * @author 劉小將
 * @packageName:com.cnblogs.lxj
 * @ClassName:SelectSort
 * @Description:測試選擇排序
 * @date 2020/11/23
 */
public class SelectSort {

    /**
     * 選擇排序方法
     */
    public static void selectSort(int[] a){
        int i = 0;
        int j = 0;
        int minIndex;
        for(i = 0;i < a.length;i++){
            minIndex = i;
            for(j = i + 1;j < a.length;j++){
                if(a[j] < a[minIndex]){
                    minIndex = j;
                }
            }
            if(i != minIndex){
                int temp = a[i];
                a[i] = a[minIndex];
                a[minIndex] = temp;
            }
        }
    }

    /**
     * 輸出方法
     * @param array
     */
    public static void printArray(int[] array){
        for(int i : array){
            System.out.print(i + " ");
        }
        System.out.println();
    }

    /**
     * 主方法
     * @param args
     */
    public static void main(String[] args){
        int[] a = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
        printArray(a);
        selectSort(a);
        printArray(a);
    }

}

執行結果:

3 44 38 5 47 15 36 26 27 2 46 4 19 50 48 
2 3 4 5 15 19 26 27 36 38 44 46 47 48 50

原理:


解釋:

對比陣列中前一個元素跟後一個元素的大小,如果後面的元素比前面的元素小,則用一個變數k來即住它的位置,接著第二次比較,前面“後一個元素”現在變成了“前一個元素”,繼續跟它的“後一個元素”進行比較,如果後面的元素比它要小,則用變數k記住它在陣列中的位置(下標),等到迴圈結束的時候,我們應該找到了最小的那個數的下標了,然後進行判斷,如果這個元素的下標不是第一個元素的下標,那就讓第一個元素跟它交換一下值,這樣就找到了整個陣列中最小的數了,然後找到陣列中第二小的數,讓它跟陣列中的第二個元素交換一下值,以此類推。


演算法分析:

時間效能:

排序演算法複雜度對比:lgn = log2n
選擇排序的交換操作介於0和(n-1)次之間。選擇排序的比較操作為n(n-1)/2次之間。選擇排序的賦值操作介於0和3(n-1)次之間。
比較次數O(n^2),比較次數與關鍵字的初始狀態無關,總的比較次數 N = (n-1)+(n-2)+...+1 = n * (n-1)/2。交換次數O(n),最好情況是:已經有序,交換0次;最壞情況交換n-1次,逆序交換n/2次。交換次數比氣泡排序少了很多,由於交換所需CPU時間比比較所需的CPU時間多,n值較小時,選擇排序比氣泡排序快。

穩定性:

選擇排序是給每個位置選擇當前元素最小的,比如給第一個位置選擇最小的,在剩餘元素裡面給第二個元素選擇第二小的,依此類推,直到第n-1個元素,第n個元素不用選擇了,因為只剩下它一個最大的元素了。那麼在一趟選擇,如果一個元素比當前元素小,而該小的元素又出現在一個和當前元素相等的元素後面,那麼交換後穩定性就被破壞了。比較拗口,舉個例子:序列5,8,5,2,9;我們知道第一遍選擇排序第一個元素5會和2交換,那麼原序列中兩個5的相對前後順序就被破壞了,所以選擇排序是一個不穩定的排序演算法。