JS--排序之快排和歸並


JS排序算法之快排和歸並

快速排序

原理: 選擇一個key(一般是第一個元素), 將數組划分為兩個區域. 左邊全部區域小於等於key, 右邊全部大於key. 然后在通過這種方法將每個區域划分為兩個區域. 整個過程可以遞歸實現,以此實現整個數據有序

  • 時間復雜度: O(n*log(n))
  • 最壞時間復雜度: O(n^2)
    • 最壞情況: 原數組是升序(降序), 需要排成降序(升序)
  • 不穩定的排序
  • 特性: 數組分塊,且左邊區域小於右邊(升序)
  • 不穩定原因: 元素交換是跨元素直接交換, 相鄰相同元素可能發生位置交換
  • 性能: 最好的的快速排序方法

示例過程:

image.png

function quickSort(ary) {
    let n = ary.length;
        function sort(ary, start, end) {
            if(end <= start) return;
            let i = start,
                j = end,
                key = ary[start]; // 設置第一個元素為key
            while(true) {
                // 從左向右找到大於key的元素位置(大於key循環停止, i就是該元素位置)
                while(ary[++i] < key) {
                    // 到達末尾退出循環
                    if(i === end) break;
                }
                // 從右向左找到小於key的元素位置
                while(ary[--j] > key) {
                    // 到達頭部退出循環
                    if(j === start) break;
                }
                // 如果 i和j相交, 直接退出循環
                if(i>=j) break;
                // 交換左右兩邊元素
                let temp = ary[i];
                ary[i] = ary[j];
                ary[j] = temp;
            }
            // 交換key和最后一個小於key值的元素(就是arr[j])
            let temp = ary[start];
            ary[start] = ary[j];
            ary[j] = temp;
            sort(ary, start, j);
            sort(ary, j+1, end);
        }
    sort(ary, 0, n);
    return ary;
}

效果演示:

快速排序.gif

歸並排序

原理: 先將數組不斷折分為左右兩個小數組, 然后再對小數組排序並合並起來

  • 時間復雜度: O(n*log(n))
  • 穩定的排序算法
    • 穩定原因: 排序是兩兩元素值之間的互換, 相鄰相同元素位置不會被改變
  • 性能: 速度僅次與快排(如果使用遞歸方法,在處理龐大數據時可能出現內存不足情況), 比快排穩定,任何時候時間復雜度都是O(n*long(n));
  • 特點: 數組會不斷對半平分, 然后再排序合並. 先小區間有序,再大區間, 區間間隔相等.
  • 優化: TimeSort排序

示例過程:
示例過程圖

    function mergeSort(items) {
        if (items.length == 1) {
            return items;
        }
        //將數組對半平分為左右兩個數組
        var middle = Math.floor(items.length / 2),
            left = items.slice(0, middle),
            right = items.slice(middle);

        function merge(left, right) {
            var result = [];
            // 通過這個循環來排序
            while (left.length > 0 && right.length > 0) {
                if (left[0] < right[0]) {
                    /*shift()方法用於把數組的第一個元素從其中刪除,並返回第一個元素的值。*/
                    result.push(left.shift());
                } else {
                    result.push(right.shift());
                }
            }
            //合並兩個數組
            return result.concat(left).concat(right);
        }

    // 遞歸調用
    return merge(mergeSort(left), mergeSort(right));
}

效果示例

歸並排序.gif

gif來源: 排序算法-散點可視化


免責聲明!

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



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