簡單選擇排序(Simple Selection Sort)

Acx7發表於2021-04-03

介紹:

  簡單選擇排序的工作方式突出"選擇"二字,每次從待排序資料中選擇符合條件的元素放在已排序元素末尾。對於少量元素的排序,簡單選擇排序是一個有效的演算法。

思想:

  第一次從待排序的資料元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然後再從剩餘的未排序元素中尋找到最小(大)元素,然後放到已排序的序列的末尾。以此類推,直到全部待排序的資料元素的個數為零。

效能分析:

  時間複雜度:O(N^2)

  空間複雜度:O(1)

  穩定性:不穩定

程式碼實現:

// Java程式碼
class SimpleSelectionSort {
    public static void selectionSort(int[] a) {
        for (int i = 0; i < a.length - 1; i++) {// 遍歷序列
            int minIndex = i;// 記錄最小元素位置
            // 遍歷無序序列尋找最小元素
            for (int j = i + 1; j < a.length; j++) {
                if (a[j] < a[minIndex]) {// 更新最小元素下標
                    minIndex = j;
                }
            }
            // 將最小值放到已排序序列的末尾
            int temp = a[i];
            a[i] = a[minIndex];
            a[minIndex] = temp;
        }
    }
}
// C++程式碼
class SimpleSelectionSort {
public:
    static void selectionSort(int a[], int length) {
        for (int i = 0; i < length - 1; i++) {// 遍歷序列
            int minIndex = i;// 記錄最小元素位置
            // 遍歷無序序列尋找最小元素
            for (int j = i + 1; j < length; j++) {
                if (a[j] < a[minIndex]) {// 更新最小元素下標
                    minIndex = j;
                }
            }
            // 將最小值放到已排序序列的末尾
            int temp = a[i];
            a[i] = a[minIndex];
            a[minIndex] = temp;
        }
    }
};

演算法優化:

  上面程式碼一次遍歷只是找出未排序序列中的最小值,其實我們可以在遍歷過程中同時找出最小值和最大值,並把每次找出的最大值按順序放到每次排列資料的末尾。時間複雜度還是 O(N^2) ,只相對前面的減少了一半遍歷次數。

// Java程式碼
class SimpleSelectionSort {
    public static void selectionSort(int[] a) {
        int left = 0;// 標記未排序序列左邊界
        int right = a.length - 1;// 標記未排序序列右邊界
        
        while (left < right) {// 遍歷未排序序列
            int minIndex = left;// 記錄最小元素位置
            int maxIndex = left;// 記錄最大元素位置
            
            // 遍歷無序序列尋找最小元素
            for (int i = left + 1; i <= right; ++i) {
                if (a[i] < a[minIndex]) {// 更新最小元素下標
                    minIndex = i;
                }
                if (a[i] > a[maxIndex]) {// 更新最大元素下標
                    maxIndex = i;
                }
            }
            // 將最小值放到已排序序列的左末尾
            int temp = a[left];
            a[left] = a[minIndex];
            a[minIndex] = temp;
            
            if (maxIndex == left) {// 處理最大值為a[left]的特殊情況
                maxIndex = minIndex;
            }
            
            // 將最大小值放到已排序序列的右末尾
            temp = a[right];
            a[right] = a[maxIndex];
            a[maxIndex] = temp;

            ++left;// 修改未排序序列範圍
            --right;
        }
    }
}
// C++程式碼
class SimpleSelectionSort {
public:
    static void selectionSort(int a[], int length) {
        int left = 0;// 標記未排序序列左邊界
        int right = length - 1;// 標記未排序序列右邊界
        
        while (left < right) {// 遍歷未排序序列
            int minIndex = left;// 記錄最小元素位置
            int maxIndex = left;// 記錄最大元素位置
            
            // 遍歷無序序列尋找最小元素
            for (int i = left + 1; i <= right; ++i) {
                if (a[i] < a[minIndex]) {// 更新最小元素下標
                    minIndex = i;
                }
                if (a[i] > a[maxIndex]) {// 更新最大元素下標
                    maxIndex = i;
                }
            }
            // 將最小值放到已排序序列的左末尾
            int temp = a[left];
            a[left] = a[minIndex];
            a[minIndex] = temp;
            
            if (maxIndex == left) {// 處理最大值為a[left]的特殊情況
                maxIndex = minIndex;
            }
            
            // 將最大小值放到已排序序列的右末尾
            temp = a[right];
            a[right] = a[maxIndex];
            a[maxIndex] = temp;

            ++left;// 修改未排序序列範圍
            --right;
        }
    }
};

 

相關文章