1. 程式人生 > 其它 >資料結構與演算法筆記-------選擇排序

資料結構與演算法筆記-------選擇排序

技術標籤:演算法演算法資料結構java排序演算法

選擇排序

基本介紹

選擇式排序也屬於內部排序法,是從欲排序的資料中,按指定的規則選出某一元素,再依規定交換位置後達到排序的目的。

排序思想

選擇排序(select sorting) 也是一種簡單的排序方法。它的基本思想是:

第一次:從一個array陣列中找到最小值與array[0]交換,也就是說不是像冒泡那樣找到小的就交換,而是遍歷了陣列,找到最小的和array[0]交換,一次只發生一次交換

第二次:從array陣列的array[1]~~~array[n-1]中找到最小值,與array[1]交換,這個過程中也是隻發生一次交換

第三次

:array[2]變成最小值。。。。依次類推

總共通過n-1次,得到一個按排序碼從小到大排序的有序序列

img

思路

第一輪:將第一個位置當成最小數,開始迴圈遍歷餘下陣列,比他小的更新成最小值,再往後找比現在這個還小的,一輪下來,找到最小的,開始交換

第二輪:將第二個位置當成最小數,開始迴圈遍歷餘下陣列,往後面比較,發現比他小的,在更新最小值,再往後,找到剩餘數中最小的數,遍歷完之後,和第一個位置交換

第三輪:同理,從第三個位置開始

….

直到n-1輪

請聽題:

現有科大學生十位,顏值分別是[100,10,35,24,16,79,4,2,57,80],請使用選擇排序從低到高進行排序

程式碼

推導過程:

/**
 * @author 王慶華
 * @version 1.0
 * @date 2020/12/21 21:32
 * @Description TODO
 * @pojectname 簡單選擇排序
 */
public class SelectSort {
    public static void main(String[] args) {
        int[] array = {100,10,35,24,16,79,4,2,57,80};
        selectSort(array);
    }
    //選擇排序演算法
    public static void selectSort
(int[] array){ //逐步推到方式 //第一輪排序 //原始陣列[100,10,35,24,16,79,4,2,57,80] //結果:[2,10,35,24,16,79,4,100,57,80] int minIndex = 0;//用來存放,最小值的下標 int min = array[0];//假定現在最小值是陣列第一個 也充當了中間值,來交換 for (int i = 0+1; i < array.length ; i++) { if (min > array[i]){//說明我們的假定最小值不是最小值 min = array[i]; //重置最小值 minIndex = i; //重置最小值索引 } } //迴圈結束,開始交換 if (minIndex != 0) { array[minIndex] = array[0]; array[0] = min; } System.out.println("第一輪後:"+ Arrays.toString(array)); //第一輪後:[2, 10, 35, 24, 16, 79, 4, 100, 57, 80] //第二輪排序 minIndex = 1;//用來存放,最小值的下標 min = array[1];//假定現在最小值是陣列第一個 也充當了中間值,來交換 for (int i = 1+1; i < array.length ; i++) { if (min > array[i]){//說明我們的假定最小值不是最小值 min = array[i]; //重置最小值 minIndex = i; //重置最小值索引 } } //迴圈結束,開始交換 if (minIndex != 1) { array[minIndex] = array[1]; array[1] = min; } System.out.println("第二輪後:"+ Arrays.toString(array)); //第二輪後:第二輪後:[2, 4, 35, 24, 16, 79, 10, 100, 57, 80] //依次類推 } }

在推導過程中,我們發現我們每次for迴圈之前,開始的標記,比上一輪for迴圈開始的位置+1了

那麼我們可以用for迴圈來解決

/**
 * @author 王慶華
 * @version 1.0
 * @date 2020/12/21 21:32
 * @Description TODO
 * @pojectname 簡單選擇排序
 */
public class SelectSort {
    public static void main(String[] args) {
        int[] array = {100,10,35,24,16,79,4,2,57,80};
        System.out.println("排序前"+Arrays.toString(array));
        selectSort(array);
        System.out.println("排序後"+Arrays.toString(array));
    }
    //選擇排序演算法
    public static void selectSort(int[] array){
        for (int i = 0; i < array.length -1 ; i++) {
            int minIndex = i;
            int min = array[i];
            for (int j = i+1; j <array.length ; j++) {
                if (min > array[j]){//說明假定的最小值不是最小
                    min = array[j];//重置min
                    minIndex = j;//重置最小值下標
                }
            }
            //交換
            if (minIndex != i){
                array[minIndex] = array[i];
                array[i] = min;
            }
            System.out.println("第"+i+"輪排序的結果是");
            System.out.println(Arrays.toString(array));
        }
    }
}

我們來語言加深一下記憶:

外層迴圈控制第幾輪排序,內層迴圈是用來控制我們的排序開始的位置

其中,優點在哪?我們發現我們的資料交換的方式跟我們的氣泡排序不一樣了,因為這裡是一次交換,不像是我們的氣泡排序那樣,每次達到要求就交換,所以我們的選擇排序,用了最小值下標這個中間輔助變數,用來只發生一次變化

那有人會覺得,若是我第N輪恰好不用交換呢?我們發現我們交換的時候多了一層if判斷,這個if判斷就是用來判斷,當前最小值下標是不是我們一開始假定的最小值的下標,如果不是在交換,是的話就直接輸出了,不發生交換,算是一個小優化

然後我們測一測選擇排序去排序一個array[80000]陣列的時間,我們發現就單單2秒鐘或者3秒鐘,確實比氣泡排序快多了