1. 程式人生 > >演算法之排序篇

演算法之排序篇

 

                                                  排序=比較+交換=無序區+有序區

js自帶的排序,sort()函式。

sort()函式本質是上把所有的元素轉換成String再排序,通過ASCII來排序,就會造成大小寫,數字比較不是你想的結果

所以不推薦使用 arr.sort();

幸運的是,sort()方法是一個高階函式,可以接受一個比較函式來實現自定義的排序。修改了原陣列

'use strict';
var arr=[2,1,23,4,2,4,4];
arr.sort(function (x,y) {
    if(x>y){
        return 1
    }
    if(x<y){
        return -1;
    }
    return 0;
});
console.log("+++++++++++++",arr);   1 2 2 4 4 4 23

若對字串排序,要忽略大小寫

ar arr = ['Google', 'apple', 'Microsoft'];
arr.sort(function (s1, s2) {
    x1 = s1.toUpperCase();
    x2 = s2.toUpperCase();
    if (x1 < x2) {
        return -1;
    }
    if (x1 > x2) {
        return 1;
    }
    return 0;
}); // ['apple', 'Google', 'Microsoft']

 

1、氣泡排序:

在無序區比較相鄰的兩個數,如果前一個數大於後一個數,就將這兩個數換位置。每一次遍歷都會將本次遍歷最大的數冒泡到最後。為了將n個數排好序,需要n-1次遍歷。 如果某次遍歷中,沒有調整任何兩個相鄰的數的位置關係,說明此時陣列已排好序,可以結束程式。

<script>
    arr = [2, 3, 5, 16, 1, 2, 6, 3, 2]
    paixu(arr);
    function paixu(arr) {
        var flag = true;
        for (var i = 1; i < arr.length; i++) {    //表示本次是第i次遍歷
            for (var j = 0; j < arr.length - i; j++) {
// 比較相鄰的元素
                if (arr[j] > arr[j + 1]) {
                    // js方法交換
                    // var temp=arr[j];
                    // arr[j]=arr[j+1];
                    // arr[j+1]=temp;

                    // es6方法交換
                    [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
                    flag = false;
                }
            }
            // 走完j後還是沒有交換flag=false
            if (flag) {
                break;
            }
        }
        console.log("+++++", arr);
    }

2、選擇排序:

第i輪遍歷arr[0:n-i]選出最大的數,與arr[n-i]互換。

輸出是原序列的一個重排 ,它們通過對陣列中的元素進行比較來實現排序,

//    自定義原型函式  如splice map等都是陣列本身的原型方法。
    Array.prototype.selectSort = function () {
        var i, j;
        for (i = 1; i <=this.length-1; i++) {     // 共進行n-1趟排序  表示本次是第i趟排序,確定第幾大的位置
            var maxIndex = 0;
//            比較   找到無序區裡最大的值
            for (j = 0; j <= this.length - i; j++) {  //訪問子序列為arr[0:this.length-i]
                if (this[j] > this[maxIndex]) {//當前值大於當前最大值時,記錄索引
//                    找到最大的值
                    maxIndex = j;
                }
            }
            //交換     將最大值和有序區位置進行交換
            [this[this.length - i], this[maxIndex]] = [this[maxIndex], this[this.length - i]]
        }
    };

    var arr = [43, 21, 10, 5, 9, 15, 32, 57, 35];
    arr.selectSort();
    console.log(arr);

 

 

 

3、插入排序:有序區+無序區

<script>
    Array.prototype.insertSort = function () {
        var i, j;
        for (i = 1; i < this.length; i++) {  // i表示要插入的數字的索引,從第二個數開始前插
            var val = this[i]; // 記錄當前要插入陣列的大小
            /*
            * 用指標j(從後向前遍歷i-1得位置開始)來遍歷第i個數字前面的,已經排好序的子陣列。當j沒有指到頭,並且j的數字大於要插入的數字時,說明
            * j還要向前遍歷,直到發現一個比要插入數字小的位置pos,然後將這個數字插到pos+1處。如果j已經指到頭了,
            * 到了-1了還沒有找到比當前數字小的位置,就把當前數字放在索引0處。
            * */
            for (j=i-1;j>=0&&this[j]>val;j--) {
//              資料後移
                this[j+1]=this[j];
            }
//            插入val
            this[j+1]=val;
        }


    }
    var arr = [43, 21, 2, 3, 4, 1, 4];
    arr.insertSort();
    console.log("++++++++++", arr)
</script>

 

4、快速排序

<script>
    Array.prototype.quickSort=function (asc=true) {
      quickSort(this,0,this.length-1,asc);
    }
    function quickSort(arr,start,end) {
        if(start<end){
            // pivot記錄樞軸插入的位置;
            var pivot= partition(arr,start,end);
            quickSort(arr,start,pivot-1);   // 遞迴的對temp左邊的元素進行排序
            quickSort(arr,pivot+1,end);  // 遞迴的對temp右邊的元素進行排序
        }
    }
    // 下面這個函式完成一趟排序
    function partition(arr,start,end) {
       // temp是樞軸,是待排序元素的第一個,一趟排序後,樞軸左邊小於等於temp,右邊大於等於temp
        var temp=arr[start];
        while (start!=end) {
            while (start<end&&arr[end]>temp) {end--;}   // 從右向左掃描找到一個小於temp的元素
            if(start<end){
                arr[start]=arr[end];  // 把右邊值放到左邊
                start++; // start 右移
            }
            while (start<end&&arr[start]<temp) {start++;}
            if(start<end){
                arr[end]=arr[start];// 把左邊值放到右邊
                end--;  // end左移
            }

        }
        arr[start]=temp;  //將temp放到最終位置,完成一次排序(小於或等於)temp(大於或等於)
        return start;
    }
    var arr=[49,38,65,97,76,13,27,49];
    arr.quickSort();
    console.log("+++++++++++",arr);
</script>