排序算法02:選擇排序

算法介紹

  首先,從[0,len]中找到數組中最小的元素,讓它與第一個元素交換。接着從[1,len]中找出最小的元素,讓它與第二個元素交換。循環往復,最終使得數組從小到大排序。

可視化效果:這裏

Javascript實現

/**
 * Created by YiYing on 2017/4/22.
 */
(function (W) {

    function Selection(arr) {
        this.arr = arr;
    }

    /**
     * 選擇排序算法實現
     */
    Selection.prototype.sort = function () {
        var len = this.arr.length;
        for(var i=0;i<len;i++){
            var min = i;
            //找出最小元素
            for(var j=i+1;j<len;j++){
                if(this.less(j,min)){
                    min = j;
                }
            }
            //把最小元素放到最前面
            this.exchange(i,min);
        }
    };

    /**
     * 判斷m是否小於n
     * @param m
     * @param n
     */
    Selection.prototype.less = function (m,n) {
        //可根據不同的數據類型設置比對規則,比如json。這裏適用於數字與字符串。
        return this.arr[m]<this.arr[n];
    };

    /**
     * 交換數組中m與n的位置
     * @param m
     * @param n
     */
    Selection.prototype.exchange = function (m,n) {
        var swap    = this.arr[m];
        this.arr[m] = this.arr[n];
        this.arr[n] = swap;
    };

    /**
     * 打印排序後的數組
     */
    Selection.prototype.show = function () {
        console.log(this.arr);
    };

    /**
     * 判斷是否已排序
     * @returns {boolean}
     */
    Selection.prototype.isSorted = function () {
        var len = this.arr.length;
        for(var i=1;i<len;i++){
            if(this.less(i,i-1)){
                return false;
            }
        }
        return true;
    };

    W.Selection = Selection;
})(window);

//測試代碼
(function () {
    var arr = [4,5,6,0,3,5,21,7,9,0,1];
    var selection = new Selection(arr);
    console.log("排序前:"+selection.isSorted());
    selection.sort();
    console.log("排序後:"+selection.isSorted());
    selection.show();
})();

Java實現

package com.algs;

public class Selection {

  /**
   * 插入排序實現邏輯
   * @param arr
   */
  public static void sort(int[] arr){
    int len = arr.length;
        for (int i = 0; i < len; i++) {
            int min = i;
            for (int j = i+1; j < len; j++) {
                if (less(arr[j], arr[min])) min = j;
            }
            exchange(arr, i, min);
        }
  }

  /**
   * 比較m是否小於n
   * @param m
   * @param n
   * @return
   */
  private static boolean less(int m,int n) {
        return m < n;
    }

  /**
   * 交換m與n的位置
   * @param a
   * @param m
   * @param n
   */
  private static void exchange(int[] a, int m, int n) {
        int swap = a[m];
        a[m] = a[n];
        a[n] = swap;
    }

  public static void show(int[] a){
    for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
  }

  public static void main(String[] args) {
    int[] arr = {4,5,6,0,3,5,21,7,9,0,1};
    Selection.sort(arr);
    Selection.show(arr);
  }
}

總結

  • 運行時間和輸入無關。

    爲了找出最小元素而掃描一遍數組並不能爲下一遍掃描提供信息。長度一致,一個有序的數組或值全部相當的數組和一個無序的數組排序所需的時間一致。

  • 數據移動是最少的。

    一個長度爲N的數組只需要N次交換即可完成排序。

  • 不穩定。

    無法保證排序前與排序後重複元素的相對順序一致。舉例:序列[5,8,5,2,9],第一遍選擇第1個元素5會和2交換,那麼原序列中兩個5的相對前後順序就被破壞了,所以選擇排序不是一個穩定的排序算法。

  • 原地排序。

  • 時間複雜度爲:平方級別。

  • 空間複雜度爲:常數級別。

GitHub:https://github.com/AlbertKnag/algs-practice

上一篇:排序算法01:冒泡排序
下一篇:排序算法03:插入排序

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