搜尋
首頁web前端js教程揭秘合併排序:分治排序初學者指南

Merge Sort Demystified: A Beginner

歸併排序由約翰·馮·諾依曼於 1945 年提出,主要是為了提高大型資料集的排序效率。馮·諾依曼的演算法旨在使用分而治之的方法提供一致且可預測的排序過程。這種策略允許歸併排序有效地處理小型和大型資料集,保證在所有情況下都能實現穩定的排序,時間複雜度為 O(n log n)

合併排序採用分而治之方法,將數組分割成更小的子數組,對它們進行遞歸排序,然後將排序後的數組重新合併在一起。這種方法將問題分解為可管理的區塊,對每個區塊進行單獨排序並有效地將它們組合起來。因此,透過劃分排序工作量,該演算法即使在大型資料集上也能表現良好。

遞歸是一個函數呼叫自身來解決同一問題的較小版本的過程。它不斷分解問題,直到問題足夠簡單可以直接解決,稱為基本情況

以下是 JavaScript 中歸併排序的實現,展示如何遞歸地拆分和合併數組:

function mergeSort(arr) {
    if (arr.length 



<p>為了更好地理解歸併排序的工作原理,讓我們使用數組來演示整個過程:[38, 27, 43, 3, 9, 82, 10]</p>

<p><strong>第 1 步:遞歸除法(mergeSort 函數)</strong><br>
這個數組被遞歸地分割成更小的子數組,直到每個子數組只有一個元素。這是透過 mergeSort 函數中的以下幾行實現的:<br>
</p>

<pre class="brush:php;toolbar:false">function mergeSort(arr) {
    if (arr.length 



<p>這會停止我們的遞歸。 </p>

<p>以下是遞歸除法的展開方式:</p>

  • 初始呼叫: mergeSort([38, 27, 43, 3, 9, 82, 10])
    • 數組在中點分割: [38,27,43] 和 [3,9,82,10]
  • 上半場:

    • 合併排序([38,27,43])
      • 在中點分割:[38] 和 [27, 43]
    • 合併排序([27, 43])
      • 分為[27]和[43]
    • 子數組 [38]、[27] 和 [43] 現在是單獨的元素,可以合併。
  • 下半場:

    • 合併排序([3, 9, 82, 10])
      • 在中點分割:[3, 9] 和 [82, 10]
    • 合併排序([3, 9])
      • 分為[3]和[9]
    • 合併排序([82, 10])
      • 分為[82]和[10]
    • 子數組 [3]、[9]、[82] 和 [10] 現在已準備好合併。

第 2 步:合併已排序的子數組(合併函數)
現在,我們開始使用 merge 函數將子數組按排序順序合併在一起:

function merge(left, right) {
    let result = [];
    while (left.length && right.length) {
        if (left[0] 



<p>合併過程的工作原理如下:</p>

<p><strong>第一次合併(來自基本情況):</strong></p>

  • 合併 [27] 和 [43] → 結果為 [27, 43]
  • 將 [38] 與 [27, 43] 合併 → 結果為 [27, 38, 43]

此時,陣列的左半部已完全合併:[27, 38, 43]。

第二次合併(來自基本情況):

  • 合併 [3] 和 [9] → 結果為 [3, 9]
  • 合併 [82] 和 [10] → 結果為 [10, 82]
  • 將 [3, 9] 與 [10, 82] 合併 → 結果為 [3, 9, 10, 82]

現在,右半部已完全合併:[3, 9, 10, 82]。

第 3 步:最終合併
最後,使用 merge 函數將兩半 [27, 38, 43] 和 [3, 9, 10, 82] 合併:

比較 27(左[0])和 3(右[0])。由於 3 比較 27 和 9。將結果加上 9。
比較 27 和 10。結果加 10。
比較 27 和 82。將結果加上 27。
比較 38 和 82。結果加上 38。
比較 43 和 82。將 43 加到結果中。
新增右側數組中剩餘的元素 82。
完全合併和排序的陣列是:
[3, 9, 10, 27, 38, 43, 82].

時間複雜度: 最佳、平均和最壞情況:O(n log n)
讓我們仔細看看:

除法(O(log n)):每次將陣列分成兩半,問題的大小就會減少。由於數組在每一步都被分成兩半,因此執行此操作的次數與 log n 成正比。例如,如果有 8 個元素,則可以將它們分成兩半 3 次(因為 log2(8) = 3)。

合併(O(n)):分割數組後,演算法將較小的數組依序合併在一起。合併兩個大小為 n 的排序數組需要 O(n) 時間,因為您必須對每個元素進行一次比較和組合。

整體複雜度(O(n log n)):由於除法需要O(log n) 步驟,並且在每一步合併n 個元素,因此總時間複雜度是這兩者的乘積:O(n log n)。

空間複雜度: O(n)
合併排序需要與數組大小成正比的額外空間,因為它在合併階段需要臨時數組來儲存元素。

與其他排序演算法的比較:
快速排序:雖然快速排序的平均時間複雜度為 O(n log n),但最壞的情況可能是 O(n^2)。合併排序避免了這種最壞的情況,但當空間受到關注時,快速排序對於記憶體中排序通常更快。
冒泡排序:比合併排序效率低很多,平均和最壞情況的時間複雜度為 O(n^2)

真實世界用法
合併排序廣泛用於外部排序,其中需要從磁碟對大型資料集進行排序,因為它可以有效地處理無法放入記憶體的資料。它也通常在平行計算環境中實現,其中子數組可以利用多核心處理進行獨立排序。

此外,Python (Timsort)、Java 和C (std::stable_sort) 等函式庫和語言都依賴合併排序的變體來確保排序操作的穩定性,使其特別適合對物件和複雜資料結構進行排序。

結論
由於其穩定性、一致的性能以及對大型資料集排序的適應性,合併排序仍然是理論計算機科學和實際應用中的基本演算法。雖然QuickSort 等其他演算法在某些情況下可能執行得更快,但合併排序保證的O(n log n) 時間複雜度和多功能性使其對於記憶體受限的環境以及維護具有相同鍵的元素的順序非常有價值。它在現代編程庫中的作用確保了它在現實世界的應用程式中保持相關性。

資料來源:

  1. Knuth,Donald E. 電腦程式設計藝術,卷。 3:排序和搜尋。 Addison-Wesley Professional,1997 年,第 158-160 頁。
  2. Cormen,Thomas H. 等。算法簡介。麻省理工學院出版社,2009 年,第 2 章(歸併排序)、第 5 章(演算法複雜性)、第 7 章(快速排序)。
  3. Silberschatz、亞伯拉罕等人。資料庫系統概念。 McGraw-Hill,2010 年,第 13 章(外部排序)。
  4. 「提姆索特。」 Python 文件、Python 軟體基礎。 Python 的 Timsort
  5. 「Java 陣列.排序」。 Oracle 文檔。 Java 的 Arrays.sort()

以上是揭秘合併排序:分治排序初學者指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具