歸併排序--排序演算法

来源:https://www.cnblogs.com/coltea/archive/2023/11/03/17807314.html
-Advertisement-
Play Games

歸併排序和快速排序一樣,都是基於分治思想的應用。 通過遞歸,不斷將原數列分為兩個數列,然後再分別使其有序,最後通過歸併將兩個有序子數列合併為新的有序數列。 ...


歸併排序

介紹

歸併排序和快速排序一樣,都是基於分治思想的應用。
通過遞歸,不斷將原數列分為兩個數列,然後再分別使其有序,最後通過歸併將兩個有序子數列合併為新的有序數列。
值得註意的是,與快速排序不同,歸併排序是穩定的。


代碼實現

void merge_sort(int a[], int l, int r)
{
        if (l >= r) return;//判斷區間數據個數,為1則返回
        int  tmp[100001];//創建臨時數組
        int mid = l + r >> 1;
    	merge_sort(a, l, mid);
    	merge_sort(a, mid + 1, r);
    	int k = 0, i = l, j = mid + 1;//建立雙指針
    	while (i <= mid && j <= r)//其中一指針遍歷至結尾則終止
                if (a[i] <= a[j]) tmp[k++] = a[i++];//對比數據,誰小先加誰
                else tmp[k++] = a[j++];
    	while(i<=mid) tmp[k++] = a[i++];
    	while(j<=r) tmp[k++] = a[j++];//將剩餘數據依次放入
    	for (i = l, j = 0; i <= r; i++, j++) a[i] = tmp[j];//將排好的數據放回原數組
}

思路分析

void merge_sort(int a[], int l, int r)
{
        if (l >= r) return;//判斷區間數據個數,為1則返回
        int  tmp[100001];//創建臨時數組
        int mid = l + r >> 1;
    	merge_sort(a, l, mid);
    	merge_sort(a, mid + 1, r);

和快速排序先排序後遞歸不同,歸併排序是先遞歸,無限細分,重點在於回溯時的歸併,當遞歸到數組區間內只有1個數據時,肯定是有序的,經過歸併後返回的數組肯定也是有序的,所以我們這裡假設這個函數已經能夠實現目的,將一個數組分為兩部分然後分別排序,只需要用標記區間的起始位置和結束位置,而兩個區間的分界就是mid,而歸併的時候我們需要一個臨時存放數據的臨時數組tmp[]


int k = 0, i = l, j = mid + 1;//建立雙指針
while (i <= mid && j <= r)//其中一指針遍歷至結尾則終止
        if (a[i] <= a[j]) tmp[k++] = a[i++];//對比數據,誰小先加誰
        else tmp[k++] = a[j++];

這裡便是整個演算法最關鍵的地方:數組的歸併。

首先,我們知道,兩個區間已經分別有序,而第一個區間起點便是本次函數傳入的起點l,終點為中值mid,第二個區間起點為mid+1,終點為函數傳入的終點參數r

我們創建雙指針lij,初始位置分別指向兩個取件的起始位置,不斷互相比較,值更小的放入數組然後往後遍歷,這樣就能實現整個數組的歸併,值得註意的是,我們的判斷條件為if(a[i]<=a[j]),這樣,就能保證同樣大小的數據按照原先的順序依次進入臨時數組,實現歸併排序的穩定性。

最終,當其中一個指針遍歷到區間結尾時,結束迴圈。


while(i<=mid) tmp[k++] = a[i++];
while(j<=r) tmp[k++] = a[j++];//將剩餘數據依次放入
for (i = l, j = 0; i <= r; i++, j++) a[i] = tmp[j];//將排好的數據放回原數組

當然,我們還需要將另外一個區間剩下的數據依次擠入臨時數組,實現最終的排序,那我們就通過比較指針和終點的值來實現。

最後將排好的數據從臨時數組中依次賦給原數組。

至此,我們完成了整個歸併排序演算法的閉環,完成了功能的實現。


結尾

歸併排序和快速排序都是分治思想的體現,他們的思路不僅僅能拿來排序,也能解決一些具體問題,具體選擇哪一種演算法,就要依靠你細緻入微的觀察,結合題目的特性。

最後,歸併排序和快速排序的時間複雜度一樣,都是O(nlogn)

以上便是對歸併排序的介紹,本文由涼茶coltea撰寫,思路來自AcWing,大佬yxc的課程。


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

-Advertisement-
Play Games
更多相關文章
  • 案例一: 一百個和尚分一百個饅頭,大和尚一人分三個,小和尚三人分一個,正好分完。問大、小和尚各幾人? var num = 100; var people = 100; var big,small; for(big=0;big<=33;big++){ small=people-big; if(big* ...
  • QQ空間自動點贊評論腳本 F12 控制台 對於主頁用以下代碼 var x=5,y=10; function autoClick() { y=y+10+Math.floor(Math.random()*10); var zan = document.getElementsByClassName('it ...
  • 退款業務強耦合到售後系統中,並且業務代碼分散到各個業務層,嚴重缺乏系統的領域邊界和分層設計,重構後退款業務邏輯不強依賴售後核心業務邏輯,做到可以獨立部署。 ...
  • 什麼是 PIP? PIP 是 Python 包管理器,用於管理 Python 包或模塊。註意:如果您的 Python 版本是 3.4 或更高,PIP 已經預設安裝了。 什麼是包? 一個包包含了一個模塊所需的所有文件。模塊是您可以包含在項目中的 Python 代碼庫。 檢查是否安裝了 PIP 在命令行 ...
  • Callable(簡單) callable介面和runnable介面類似,都是為了執行另外一條線程而設計的,區別是Runnable不會返回結果也不會拋出異常。 1、可以有返回值 2、可以拋出異常 3、方法不同;run()/call(); Runnable 實現Runnable介面,重寫run方法,無 ...
  • 記得學妹剛畢業那天,為了不讓學妹畢業就失業,連夜我就用Python採集了上萬份崗位,分析出最合適她的工作。 為此,學妹連夜來我家表示感謝😍 我們開始今天的正題吧 首先要準備這些 軟體 Python 3.8 Pycharm 模塊使用 requests # 數據請求模塊 pip install req ...
  • 說明 1. 或許是全網首發,我翻過很多文章,從未有一個博主講過這個東西,很多博主只講了IOC、DI和反射機制的常見用法,因類類型形參反射的巧妙用法有相當高的難度和學習盲區,所以從未有人講過類類型的形參它怎麼就被自動實例化的。 2. 在Laravel框架,或者是其它框架中,類的成員方法中形參的類型定義 ...
  • 歡迎訪問我的GitHub 這裡分類和彙總了欣宸的全部原創(含配套源碼):https://github.com/zq2599/blog_demos 本篇概覽 -《Go語言基準測試(benchmark)三部曲》已近尾聲,經歷了《基礎篇》和《記憶體篇》的實戰演練,相信您已熟練掌握了基準測試的常規操作以及各種 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...