1. 程式人生 > >歸並排序給阿裏2萬多名員工按年齡排序

歸並排序給阿裏2萬多名員工按年齡排序

快速排序 span arr str body document rip 面試 選擇

在開始說之前先扯些面試中常見考察理解和分析問題的題目:

  • 判斷一個單詞是否是回文,
  • 去掉一組整型數組重復的值,
  • 統計一個字符串出現最多的字母,
  • 排序算法,
  • 不借助臨時變量,進行兩個整數的交換

下面我們就來看該如何去選擇算法,詳見下圖:

技術分享圖片

這裏面來講講什麽是穩定性

穩定性不能影響原來的順序,比如說現在有三個員工和各自的年齡

1:55  2:55  3:40

現在按年齡排序

3:40  1:55  2:55  穩定

3:40  2:55  1:55  不穩定(影響了原來的順序)

下面再來看看如何選擇排序方法

  • 若n較小(如n≤50),可采用直接插入或直接選擇排序
  • 若文件初始狀態基本有序(指正序),則應選用直接插入、冒泡或隨機的快速排序為宜
  • 若n較大,則應采用時間復雜度為O(n log n)的排序方法:快速排序,堆棧排序或歸並排序
  • 若n較小,考慮穩定性,可以使用:基數排序,計數排序或桶排序

考慮到穩定性,所以就選擇歸並排序

歸並排序的實現原理:拆分=>歸並

拆分:

比如數組[1,5,6,2,4,3],歸並排序的第一步,將數組一分為二:[1,5,6] [2,4,3] 接著將分成的數組繼續一分為二,直到長度為1,構成如下二叉樹:

技術分享圖片

歸並:

當遞歸到了盡頭,向上回溯,對於兩個有序的數組,我們將它們合並成一個有序數組,完成整個歸並排序(從下往上)

下面來看代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript">
        //歸並
        function merge(left, right){
            var result = [];//作為中間容器,臨時存放
if(left[0] < right[0]){ result.push(left.shift()); }else{ result.push(right.shift()); } return result.concat(left).concat(right); } //拆分 function mergeSort(arr){ var mid = arr.length / 2; var left_arr = arr.slice(0, mid); var right_arr = arr.slice(mid); // console.log(left_arr); // console.log(right_arr); return merge(left_arr, right_arr); } var arr = [6,4]; console.log(mergeSort(arr)); </script> </body> </html>

代碼兩步走,先拆分再歸並

輸出結果:

技術分享圖片

但是當數組的長度加長的時候就會出現問題:

var arr = [6,4,7];

此時瀏覽器的結果:

技術分享圖片

這顯然不是我們要的結果,這時候我們還要再加入拆分和判斷,代碼如圖:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript">
        //歸並
        function merge(left, right){
            var result = [];//作為中間容器,臨時存放
            while(left.length > 0 && right.length > 0){
                if(left[0] < right[0]){
                result.push(left.shift());
                }else{
                    result.push(right.shift());
                }
            }
            
            return result.concat(left).concat(right);
        }
        //拆分
        function mergeSort(arr){
            if(arr.length == 1){
                return arr;
            }
            var mid = arr.length / 2;
            var left_arr = arr.slice(0, mid);
            var right_arr = arr.slice(mid);
            // console.log(left_arr);
            // console.log(right_arr);
            return merge(mergeSort(left_arr), mergeSort(right_arr));
        }
        var arr = [6,4];
        console.log(mergeSort(arr));
    </script>
</body>
</html>

這個時候就實現了排序,給數組加入一些數據測試一下:

var arr = [6,4,7,3,7,3,2,6];

結果:

技術分享圖片

歸並排序給阿裏2萬多名員工按年齡排序