JS--排序之快排和歸併

来源:https://www.cnblogs.com/luoshuifushen/archive/2020/03/21/12542020.html
-Advertisement-
Play Games

JS排序演算法之快排和歸併 [Toc] 快速排序 原理: 選擇一個key(一般是第一個元素), 將數組劃分為兩個區域. 左邊全部區域小於等於key, 右邊全部大於key. 然後在通過這種方法將每個區域劃分為兩個區域. 整個過程可以遞歸實現,以此實現整個數據有序 + 時間複雜度: O(n log(n)) ...


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來源: 排序演算法-散點可視化


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Vue是MVVM設計模式的前端框架,其實現Todolist相比於通過Jquery操作Dom來實現的方法是非常簡潔的。下麵我就來對比下這兩種方法。 Vue實現 可以看到,vue實現todolist僅僅是對Model層進行的操作,既對數據進行操作,在操作完成後,vue內置的ViewModel層會自動對數 ...
  • ```js 點擊 ``` ...
  • 1、求出1 2018中所有含8的數字,使用數組的reduce、map、filter方法,如1 10中:8;1 20中:8,18; 最後拼湊著使用了三個方法,完成了這個題目,不知道題目我是不是沒理解清楚,是必須用到這三個函數還是只用其中之一就可,如果只用reduce,也可以實現,如下 2、解析url中 ...
  • 如下代碼 2、回調函數 3、async await ...
  • 產生原因 如果從後端返回過來的數組數據,進行遍歷的時候不在success回調函數內,則會產生如下的數據格式,雖然其也是數組格式,但是內部的值取不出來,給後臺也傳不過去。 原因:其實跟__ob__: Observer這個屬性沒有多少關係,原因還是在於非同步,因為wx.chooseImage是一個非同步執行 ...
  • 1、數組扁平化(數組降維) 數組扁平化是指將一個多維數組變為一維數組 [1, [2, 3, [4, 5]]] > [1, 2, 3, 4, 5] 2、給定一個數組,將數組中的所有0移動到末尾,並保持非0元素的順序不改變。如 [0,1,0,3,12] 移動後的期望數組為 [1,3,12,0,0] 要求 ...
  • 經過昨天對移動端基礎的瞭解,今天就來用原生JS實現一下我們的幻燈片。 因為是用原生實現,所以本文篇幅較長,各位看官只需理解思路即可,代碼部分可以粗略看看。 畢竟我們有better-scroll這樣封裝好的框架能更快速實現效果。b( ̄▽ ̄)d 首先根據我們昨天的滑屏操作,先將幻燈片的滑屏效果做出來。這 ...
  • 排序演算法之堆排序 [Toc] 什麼是堆? + 堆是一顆完全二叉樹 + 堆分為 最大堆和最小堆 + 最大堆父節點都大於子節點, 最小堆父節點都小於子節點 + 左子節點: 2 i +1 (i: 父節點index) + 右子節點: 2 i+2 堆排序 利用最大堆實現升序, 最小堆實現降序. 因為最大堆的根 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...