被排序算法吊打之—選擇排序

在這裏插入圖片描述

1. 選擇排序思想

選擇排序,就是通過選擇,將元素放到合適的位置上。那麼,如何進行選擇呢?

舉個例子,大家在買東西時,一定會貨比三家吧。我們肯定是希望花最少的錢,買最優的貨,這種比較選擇,就是選擇排序的思想。

我現在要在某寶買三頂假髮,在購物車添加了五個不同的店家商品(假定我只在一家店只買一件商品)。首先,我會以一家的價錢作爲標準,然後和其他四家店的價格比較。比完之後我會選出一件最便宜的付款,然後再剩下的四家中再次選出最便宜的進行比較購買。這就是選擇排序的選擇

2. 選擇排序詳解

對序列【4 , 6 , 8 , 7 , 6 , 2 , 9 , 1】遞增排序
在這裏插入圖片描述

  • 我們讓min作爲進行選擇探測的指針

  • 對原數據而言,假定第一個索引處的元素是最小值,即當前min = 4

  • 第一趟排序:min依次和之後索引處的數進行比較,當它到索引5所指向的數2時,發現此索引處的數比自己小,於是讓自己指向當前元素,即min = 2;然後min繼續向後探測,發現末尾索引處元素2比自己還小,繼續更換,min = 1

在這裏插入圖片描述

  • 此時,遍歷完了序列,min發現自己等於1時是最小的。於是和當初假裝自己是最小的4進行交換位置
  • 交換完之後,min後移一位,然後又假裝此時自己指向的是最小的元素,第二趟選擇排序開始
  • 以此類推繼續排序。倘若比較完後·min位置的元素是最小值,那就無需交換,不動即可

在這裏插入圖片描述

  • 直到剩餘最後一個元素時,min也不用假裝自己指向的最小元素了,這次是真的了。只剩一個了,一定是最大的了,就不用管了。到此,選擇排序完成!

【動圖詳解】
在這裏插入圖片描述


選擇排序就是通過改變——指向最小元素索引的位置來尋找每趟最小的數,每趟遍歷交換指針min指向的值,來比較確定出每趟的最小元素,之後交換元素位置


3. 代碼實現

外層循環完成了數據交換,內層循環完成了數據比較

public static void selectSort(int[] arr) {
        //參與選擇排序的元素:只剩一個元素時不用選擇,到倒數第二個元素截止
        for (int i = 0; i < arr.length - 1; i++) {
            //假定本次遍歷最小值所在的索引是i,默認第一個
            int minIndex = i;
            //讓當前最小元素與它後面的元素依次進行比較
            for (int j = i + 1; j < arr.length; j++) {
                if(arr[minIndex] > arr[j]) {
                    //交換最小值所在的索引
                    minIndex = j;
                }
            }
            //將最小元素所在索引minIndex處的值與i索引的值交換
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }

測試

在這裏插入圖片描述

歸併排序後爲:[1, 2, 4, 6, 6, 7, 8, 10]

4. 複雜度分析

【時間複雜度】

選擇排序使用了雙層for循環,其中外層循環完成了數據交換,內層循環完成了數據比較,數據
交換次數和數據比較次數:

數據交換次數:N-1

數據比較次數:(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)*(N-1)/2=N^2/2-N/2

時間複雜度:N^2 / 2 - N / 2 + (N-1) = N ^ 2/2 + N/2-1;

根據大O推導法則,保留最高階項,去除常數因子,時間複雜度爲O(N^2)

【空間複雜度】O(1)


《被排序算法吊打系列彙總》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章