js算法之最常用的排序


引入

  大學學習計算機語言的那幾年,從c語言,到c++,再到數據結構JAVA..讓我印象最深刻的還是最開始老師講冒泡算法的時候,直到現在大四快畢業了我才漸漸通竅了。剛學前端的時候以為前端就是做出好看很炫的頁面就行了,后來才漸漸懂得前端不只是頁面仔。一次美團面試,面試官說他們要的不僅是前端,他們要的是“工程師”,從面試開始到結束問都是算法,頓時把我給打擊了。二叉樹、基本算法還有時間復雜度都是很重要的東西,不僅體現了一個前端的學習深度,還體現了一名計算機學生的專業水平。所以,為了查缺補漏,我決定開始研究一下程序猿最愛提的算法,今天聊聊最常用的排序算法。魷魚看過很多資料覺得都太專業化了,根本看不懂,所以以下我都盡量用能讓自己(別人)看懂的介紹來描述啦~

 

常用排序算法

  • 冒泡排序(Bubble sort)

    大白話介紹:比較相鄰的兩個數,如果后面的比前面的小,把小的放在前面。

    時間復雜度:  O(n2)

      動畫演示冒泡排序

    實際代碼

方法一:
function
bubbleSort(arr){ for(var i=0;i<arr.length-1;i++){ for(var j=0;j<arr.length-1;j++){ if(arr[j+1]<arr[j]){ temp = arr[j+1]; arr[j+1] = arr[j]; arr[j] = temp; } } } return arr; }

//對比arr中的第j+1項和第j項,如果第j+1項小於第j項,就把第j+1項和第j項調換位置。如果沒達到最終的順序(從小到大),就繼續找,繼續換,直到達到最終效果

但是上面的方法並不完美,如果數組已經是有序了,就沒必要再比較了,所以下面有一種優化冒泡排序算法:

 

優化冒泡排序算法

方法二(優化算法):
function
bubbleSort(arr){ var flag = false; // 定義一個變量為false,未交換位置 for(var i=0;i<arr.length-1;i++){ for(var j=0;j<arr.length-1;j++){ if(arr[j+1]<arr[j]){ temp = arr[j+1]; arr[j+1] = arr[j]; arr[j] = temp; flag = true; //true,已交換位置 } } if(flag){ flag = false; //如果交換了位置,將flag重新設為false }else{ break; //如果未交換,則跳出循環 } } return arr; }


或者寫成這樣~
function bubbleSort(arr){
    var flag;
    for(var i=0;i<arr.length-1;i++){
        flag =false;
        for(var j=0;j<arr.length-1;j++){
            if(arr[j+1]<arr[j]){
                temp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = temp;
                flag = true;
            }
        }
        if(!flag){
            return arr;
        } 
    }
    return arr;
}

 

  • 選擇排序(selection Sort)

    大白話介紹:在亂序的數組中選擇最小的值,然后和每次循環后的數組的第一位進行交換

    時間復雜度:O(n2)

      動畫演示選擇排序

    實際代碼:   

var arr=[5,3,2,4,1,0];
function
findMin(arr,first){ var minindex = first; //定義最小下標 var minNum = arr[first]; //定義數組中的最小值 for(var i=first+1;i<arr.length;i++){ //循環找到最小值和最小下標 if(arr[i]<minNum){ minNum = arr[i]; minindex = i; } }
return minindex;//返回最小值下標 一共查找了六次,最小值下標分別為 :5,4,2,4,4,5 } function selectionSort(arr){ for(var i=0;i<arr.length;i++){ var min =var temp = arr[min]; arr[min] = arr[i]; //eg.第一次循環 :將最小值5和arr[0]進行交換 arr[i] = temp; // 剩下幾次同第一次 } return arr; } document.write(selectionSort(arr)); //0,1,2,3,4,5,

     排序過程:(自己畫的一個粗糙的框框表嫌棄)

 

        

 

  • 歸並排序(mergeSort)

    大白話介紹:   把一個數組分為兩個數組,左邊排好序,右邊排好序,然后合並到一起排序

      專業性介紹:   歸並排序是分治法的典型實例,指的是將兩個已經排序的序列合並成一個序列的操作

    時間復雜度:   O(nlogn)

    動畫演示:歸並排序

    實際代碼:

     var arr=[-11,17,12,19,0,-222];
     function mergeSort(arr,s,e){
         if(s>e){   //起始位置大於終點位置,返回空數組
             return [];
         }else if(s==e){
             return [arr[s]]; //起始位置等於終點位置,說明數組里只有一個數字,返回只含一個數字的數組    
         }

         var mIndex = Math.floor((s+e)/2); //中間位置的Index
         var arrL = mergeSort(arr,s,mIndex); //將左邊的數組排序
         var arrR = mergeSort(arr,mIndex+1,e); //將右邊的數組排序
         
         var resultArr = []; //結果數組
         while(arrL.length>0 || arrR.length>0){ //當左右兩個數組都不為空時
             if(arrL[0]<arrR[0]){
                 resultArr.push(arrL.shift());
             }else{
                 resultArr.push(arrR.shift());
             }

             if(arrL.length==0){  //當左邊的數組為空時
                 resultArr = resultArr.concat(arrR);
                 break;
             }else if(arrR.length==0){
                 resultArr = resultArr.concat(arrL);
                 break;
             }
         }
         return resultArr;
     }

     document.write(mergeSort(arr,0,arr.length-1));

  排序過程:

     

 

  • 快速排序(quickSort)

  大白話介紹:引用阮一峰老師的一句話,感覺是極好理解的~(我的目標也是成為像阮一峰老師這樣的)

 (1)在數據集之中,選擇一個元素作為"基准"(pivot)。

 (2)所有小於"基准"的元素,都移到"基准"的左邊;所有大於"基准"的元素,都移到"基准"的右邊。

 (3)對"基准"左邊和右邊的兩個子集,不斷重復第一步和第二步,直到所有子集只剩下一個元素為止。 

     實際代碼:

    var arr=[77,-33,22,32,0,2,11];
    function quickSort(arr){
        if(arr.length<=1){ //如果數組中只有一位數,返回數組
            return arr;
        }
        var mNumIndex = Math.floor(arr.length/2); //取基准值的下標
        var mNum = arr.splice([mNumIndex],1)[0];  //取基准值
        var left = [];  //左邊數組
        var right = []; //右邊數組
        
        for(var i=0;i<arr.length;i++){
            if(arr[i]<mNum){  //如果數組小於基准值,放在左邊數組
                left.push(arr[i]);
            }else{            ///否則
                right.push(arr[i]);
            }
        }        
        return quickSort(left).concat([mNum],quickSort(right)); //返回左邊數組+基准值+右邊數組
    }

    document.write(quickSort(arr));

  排序過程:

 

 

      以上就是一些常見的排序了,但是還有很多常見的排序沒有提到~~ 后期還會寫一個常用排序二~敬請期待噢 ~希望我學到的東西也能幫助到大家~有說錯的地方歡迎批評指正~

 

 

  學習資料:

  http://bubkoo.com/2014/01/15/sort-algorithm/merge-sort/ 

      http://www.cnblogs.com/binking338/p/3440296.html

      http://www.webhek.com/misc/comparison-sort

      http://www.cnblogs.com/CareySon/archive/2011/10/28/2227703.html

       http://bubkoo.com/2014/01/15/sort-algorithm/merge-sort/

      http://www.cnblogs.com/wteam-xq/p/4752610.html

     http://www.ruanyifeng.com/blog/2011/04/quicksort_in_javascript.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM