選擇排序就這麼簡單

選擇排序就這麼簡單

從上一篇已經講解了冒泡排序了,本章主要講解的是選擇排序,但願你們看完可以理解並手寫出選擇排序的代碼,而後就經過面試了!若是我寫得有錯誤的地方也請你們在評論下指出。html

選擇排序介紹和穩定性說明

來源百度百科:java

選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工做原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始(末尾)位置,直到所有待排序的數據元素排完。選擇排序是不穩定的排序方法(好比序列[5, 5, 3]第一次就將第一個[5]與[3]交換,致使第一個5挪動到第二個5後面)。

上面提到了選擇排序是不穩定的排序方法,那咱們的冒泡排序是否是穩定的排序方法呢?穩定的意思指的是什麼呢?面試

判斷某排序算法是否穩定,咱們能夠簡單理解成:排序前2個相等的數其在序列的先後位置順序和排序後它們兩個的先後位置順序相同算法

  • 若是相同,則是穩定的排序方法。
  • 若是不相同,則是不穩定的排序方法

若是排序前的數組是[3,3,1],假定咱們使用選擇排序的話,那第一趟排序後結果就是[1,3,3]。這個數組有兩個相同的值,它倆在array[0]array[1],結果通過排序,array[0]的跑到了array[2]上了。數組

那麼這就致使:2個相等的數其在序列的先後位置順序和排序後它們兩個的先後位置順序不相同,所以,咱們就說它是不穩定的微信

再回到上面的問題,上一篇說講的冒泡排序是穩定的,主要緣由是:倆倆比較的時候,沒有對相等的數據進行交換(由於不必)。所以它不存在2個相等的數其在序列的先後位置順序和排序後它們兩個的先後位置順序不相同。優化

那麼穩定排序的好處是什麼?spa

  • 參考知乎回答@獨行俠的回答:
若是咱們只對一串數字排序,那麼穩定與否確實不重要,由於一串數字的屬性是單一的,就是數字值的大小。可是排序的元素每每不僅有一個屬性,例如咱們對一羣人按年齡排序,可是人除了年齡屬性還有身高體重屬性,在年齡相同時若是不想破壞原先身高體重的次序,就必須用穩定排序算法.

很清晰的指出,只有當在「二次」排序時不想破壞原先次序,穩定性纔有意義code

參考資料:htm

1、第一趟排序

它的工做原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始(末尾)位置,直到所有待排序的數據元素排完

首先,咱們建立數組,找到它最大的值(這就很簡單了):

int[] arrays = {2, 3, 1, 4, 3, 5, 1, 6, 1, 2, 3, 7, 2, 3};

    //假定max是最大的
    int max = 0;


    for (int i = 0; i < arrays.length; i++) {
        if (arrays[i] > max) {
            max = arrays[i];
        }
    }

隨後這個最大的數和數組末尾的數進行交換:

//使用臨時變量,讓兩個數互換
    int temp;
    temp = arrays[11];
    arrays[11] = arrays[13];
    arrays[13] = temp;

那麼通過第一趟排序,咱們的最大值已經到了數組的末尾了。

2、第二趟排序

再次從數組獲取最大的數(除了已經排好的那個):

int max2 = 0;
    for (int i = 0; i < (arrays.length - 1); i++) {
        if (arrays[i] > max2) {
            max2 = arrays[i];
        }
    }

    System.out.println(max2);

再將獲取到的最大值與數組倒數第二位交換:

temp = arrays[7];
    arrays[7] = arrays[12];
    arrays[12] = temp;

通過第二次排序,已經可以將數組最大兩個數進行排序了

3、代碼簡化

從前兩趟排序其實咱們就能夠摸出規律了:

  • 一個數組是須要n-1趟排序的(由於直到剩下一個元素時,纔不須要找最大值)
  • 每交換1次,再次找最大值時就將範圍縮小1
  • 查詢當前趟數最大值實際上不用知道最大值是多少(上面我查出最大值,還要我手動數它的角標),知道它的數組角標便可,交換也是根據角標來進行交換

第一趟:遍歷數組14個數,獲取最大值,將最大值放到數組的末尾[13]
第二趟:遍歷數組13個數,獲取最大值,將最大值放到數組倒數第二位[12]

....

數組有14個數,須要13趟排序。

//記錄當前趟數的最大值的角標
    int pos ;

    //交換的變量
    int temp;


    //外層循環控制須要排序的趟數
    for (int i = 0; i < arrays.length - 1; i++) {

        //新的趟數、將角標從新賦值爲0
        pos = 0;

        //內層循環控制遍歷數組的個數並獲得最大數的角標
        for (int j = 0; j < arrays.length - i; j++) {
            
            if (arrays[j] > arrays[pos]) {
                pos = j;
            }

        }
        //交換
        temp = arrays[pos];
        arrays[pos] = arrays[arrays.length - 1 - i];
        arrays[arrays.length - 1 - i] = temp;


    }

    System.out.println("公衆號Java3y" + arrays);

4、選擇排序優化

博主暫未想到比較好的優化方法,若是看到這篇文章的同窗知道有更好的優化方法或者代碼可以寫得更好的地方,歡迎在評論下留言哦!

查到的這篇選擇排序優化方法,感受就把選擇排序變了個味,你們也能夠去看看:

5、擴展閱讀

C語言實現

int findMaxPos ( int arr[], int n)
        {
            int max = arr[0];
            int pos = 0; 
            for (int i = 1; i < n; i++) {
                if (arr[i] > max) {
                    max = arr[i];
                    pos = i;
                }
            }
            return pos;
        }

        void selectionSort ( int arr[], int n)
        {
            while (n > 1) 
            {
                int pos = findMaxPos(arr, n);
                int temp = arr[pos];
                arr[pos] = arr[n - 1];
                arr[n - 1] = temp;
                n--;//
            }
        }

        int main ()
        {
            int arr[] = {5, 32, 7, 89, 2, 3, 4, 8, 9};
            selectionSort(arr, 9);
            for (int i = 0; i < 9; i++)
                cout << arr[i] << endl;
        }
若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠 關注微信公衆號:Java3y
相關文章
相關標籤/搜索