【算法】Merge Sort 合并排序

Merge Sort概述

分而治之算法

遞歸地將問題分解為多個子問題,直到它們變得簡單易解
將解決方案組合起來,解決原有問題

O(n*log(n))運行時間

基于比較的算法的最佳運行時間

一般原則
·合并排序:
1. 將數組分成兩半
2.在每一半上調用合并排序以遞歸排序
3.將兩個已排序的兩半合并為一個已排序數組

看一個例子:

2,6,5,1,7,4,3

首先第一步,是將數組分成兩半,分到直到分不了了。

然后現在,對每組數據進行排序。

2,6

1,5

4,7

然后,再一組一組排序:
1,2,5,6

3,4,7

然后最后兩組排序

1,2,3,4,5,6,7

注意這里是,1和3比,選1,2和3比,選2,5和3比,選3,4和5比,選4。。。

Python實現MergeSort合并排序

def merge_sort(arr):if len(arr) > 1: #要保證大于1才能排序left_arr = arr[:len(arr)//2] #定義2個子數組,這個是從索引0到中心點,:左留下空白就是取左邊所有right_arr = arr[len(arr)//2:] #這個是從中心點到右邊# 遞歸merge_sort(left_arr)merge_sort(right_arr) #分別再左右兩個數組進行遞歸# 執行以上兩行以后,左右兩個數組都按照順序排列了# 合并# 現在兩個數組已經拍好順序,我們想讓兩個數組,第一個數組的最左邊和第二個數組最左邊進行比較# 所以,創建索引進行追蹤i = 0 #追蹤第一個左邊數組j = 0 #追蹤右邊k = 0 #追蹤合并數組中的索引while i < len(left_arr) and j < len(right_arr):if left_arr[i] < right_arr[j]:#如果左邊的數組值小arr[k] = left_arr[i] # 保存索引對應的值i += 1#k += 1#因為我們取得是i的值,所以,必須i+1進入下一個索引,而且,k是合并后的數組,也要進入下一個else:arr[k] = right_arr[j]j += 1#k += 1k += 1  #簡略后,放這里# 現在只考慮轉移左邊的數組,不考慮右邊的數組;# 這是假設,右邊都排好了,但是左邊沒排完while i < len(left_arr):arr[k] = left_arr[i]i += 1k += 1# 假設左邊都排好了,但是右邊還要排while j < len(right_arr):arr[k] = right_arr[j]j += 1k += 1arr_test = [2,3,5,1,7,4,4,4,2,6,0]
merge_sort(arr_test)
print(arr_test)

問題:
?

 merge_sort(left_arr)
2    merge_sort(right_arr) #分別再左右兩個數組進行遞歸
3    # 執行以上兩行以后,左右兩個數組都按照順序排列了    這里是什么意思?是直接調用我定義的函數嗎?函數不是沒寫完嗎?

這里正是體現了遞歸函數的工作原理。當你在代碼中調用 merge_sort(left_arr)merge_sort(right_arr) 時,你實際上是在調用當前函數自身,但是傳入了不同的參數——即左側子數組和右側子數組。

雖然從直觀上看,函數“還沒有寫完”,但實際上,每次調用 merge_sort 函數時,它都在執行完整的邏輯流程:

  1. 檢查當前數組的長度是否大于1,如果是,則繼續執行。
  2. 將當前數組分割成兩個子數組(左側和右側)。
  3. 對這兩個子數組分別遞歸調用?merge_sort?函數。這里就是遞歸發生的地方,每一次這樣的調用都會重復整個過程,直到數組被拆分到不能再拆分(即長度為1或0,視為已排序)。
  4. 最后,通過合并這些小數組來完成排序。

因此,即便在某次調用中函數尚未執行到合并步驟,之前的調用(處理更小規模數組的那些調用)已經在逐步完成它們的任務。當這些更深層次的遞歸調用返回時,它們會逐級返回到上一層,最終回到最初的函數調用,這時所有子數組都已經排序完畢,可以進行最終的合并,完成整個數組的排序。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/38230.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/38230.shtml
英文地址,請注明出處:http://en.pswp.cn/web/38230.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

elasticsearch鏡像化安裝部署

1、鏡像安裝 docker network create --driver bridge --subnet192.128.0.0/10 --gateway192.128.1.1 mynetwork docker run -d --netmynetwork --ip192.128.10.1 -p 1000:22 --name redhat-es01 -it c70d72aaebb4 /bin/bash #拉取鏡像 docker pull elasticsearch:7.7.0 #啟動…

【瞎折騰日常】服務器的cpu飆高到1000%了怎么破

一、故障起因 起因是用戶反饋系統很卡,我登錄普羅米修斯一看,發現docker部署得集群下的一個java應用服務器cpu爆了,直接沖到了1000%以上了,接著就是各種接口超時報警等,趕緊打開對應的服務器查看進程情況,這會使用jstack和top命令定位哪個線程占用的cpu比較大,定位代碼問…

橢流線法設計配光器

橢流線法設計配光器 一、設計原理 1、邊光原理 邊光原理是非成像光學中的一個基礎原理&#xff0c;其內容可以表述為&#xff1a;來自光源邊緣的光線經過若干有序正則光學曲面后依然落在投射光斑的邊緣&#xff0c;而來自光源內部的光線也將落在光斑內部。這里的邊緣包含兩層…

PyTorch(七)模型的保存與加載

#d 兩種保存方式比較 僅保存模型參數 優點: 更加靈活&#xff0c;只保存模型的參數&#xff0c;不保存模型的結構&#xff0c;可以在不同的模型結構中加載參數&#xff08;只要參數匹配&#xff09;。文件大小通常比保存整個模型小。安全性更高&#xff0c;因為不直接執行pic…

機械拆裝-基于Unity-總體設計

前言 在工業設計和制造領域&#xff0c;零部件的拆裝技術是一個重要的應用場景&#xff0c;比如我們在工程訓練課程中經歷的摩托車發動機拆裝課程&#xff0c;是機械類學生的必修課程。虛擬拆裝系統模擬和仿真了模型的拆裝過程&#xff0c;雖然SolidWorks等機械設計軟件能夠解決…

性能調優 性能監控

1.影響性能考慮點包括&#xff1a; 數據庫、應用程序、中間件(tomcat、nginx)、網絡和操作系統等方面。 首先考慮自己的應用屬于 CPU密集型 還是 IO密集型 cpu密集型 計算&#xff0c;排序&#xff0c;分組查詢&#xff0c;各種算法 IO密集型 網絡傳輸&#xff0c;磁盤讀…

大創項目推薦 題目:基于機器視覺opencv的手勢檢測 手勢識別 算法 - 深度學習 卷積神經網絡 opencv python

文章目錄 1 簡介2 傳統機器視覺的手勢檢測2.1 輪廓檢測法2.2 算法結果2.3 整體代碼實現2.3.1 算法流程 3 深度學習方法做手勢識別3.1 經典的卷積神經網絡3.2 YOLO系列3.3 SSD3.4 實現步驟3.4.1 數據集3.4.2 圖像預處理3.4.3 構建卷積神經網絡結構3.4.4 實驗訓練過程及結果 3.5 …

zabbix報警機制,主動監控

zabbix思路流程 主動監控 默認zabbix使用的是被動監控&#xff0c;主被動監控都是針對被監控主機而言的。被動監控&#xff1a;Server向Agent發起請求&#xff0c;索取監控數據。此種模式常用主動監控&#xff1a;Agent向Server發起連接&#xff0c;向Server匯報 配置web2使用…

STM32智能家居掌上屏實戰:從WiFi連接到MQTT通信,打造你的家庭物聯網網關

摘要: 本文深入探討一種基于STM32的智能家居掌上屏設計方案&#xff0c;詳細闡述其硬件架構、軟件設計以及通信協議等關鍵技術細節。該方案利用WiFi構建局域網&#xff0c;實現與各類傳感器、執行器的便捷交互&#xff0c;并通過TFT彩屏提供直觀的控制和數據展示&#xff0c;旨…

[數據庫原理]事務

如有錯誤&#xff0c;歡迎指正&#xff01;&#xff01;&#xff01; 期末考了沖突可串行化

動態順序表實現通訊錄

系列文章目錄 【數據結構】順序表 文章目錄 系列文章目錄前言一、通訊錄的功能要求二、通訊錄的代碼實現1. 新建文件2. 創建通訊錄的結構體3. 對順序表文件進行修改4. 通訊錄具體功能實現4.1. 通訊錄的初始化和銷毀4.2. 增加聯系人信息&#xff08;尾插&#xff09;4.3. 查找指…

SpringBoot + 虛擬線程,性能炸裂!

一、什么是虛擬線程 虛擬線程是Java19開始增加的一個特性&#xff0c;和Golang的攜程類似&#xff0c;一個其它語言早就提供的、且如此實用且好用的功能&#xff0c;作為一個Java開發者&#xff0c;早就已經望眼欲穿了。 二、虛擬線程和普通線程的區別 “虛擬”線程&#xf…

一些硬件知識(十二)

X電容是接在火線和零線之間&#xff0c;Y電容是接在火零線和地之間。X電容濾除差模干擾&#xff0c;Y電容濾除共模干擾&#xff1a; 高頻干擾信號經過X電容后幅度沒有變化&#xff0c;相位相差180度&#xff1a; DW01電池管理芯片&#xff1a; M1、M2&#xff1a;這兩個為N溝道…

【關于C/C++中的scanf不能使用問題】

方法1&#xff1a;scanf_s 方法2&#xff1a;看見后面的日志了嗎 CRT……&#xff1f;在第一行加上#define 日志 方法3&#xff1a;#pragma warning&#xff08;disable&#xff1a;4996&#xff09; 4996是我們的報錯序號

開發筆記:vue3+ts+vant 卡片數據分頁,下拉加載,卡片左滑可刪除

效果&#xff1a; 實現 使用vantui組件 van-swipe-cell van-card &#xff08;商品卡片&#xff09; 核心代碼 const currentPage ref(1) const pageSize ref(4) const totalSize ref(10) const loading ref(false) const finished ref(false) const refreshing ref(…

Git新倉庫創建流程

平時需要創建新倉庫,老要去查代碼特別煩&#xff0c;在此寫下流程方便備用. 1.創建新的云倉庫 無論使用GitHub還是Gitee,首先要創建一個云倉庫&#xff0c;這里就直接用國內的gitee做演示了&#xff0c;githup老掛加速器太煩&#xff0c;偷個懶. 我這里創建的是一個空倉庫&…

java- Lambda表達式的實際應用

### 12. Lambda 表達式的實際應用 為了更好地理解和應用 Lambda 表達式&#xff0c;我們可以通過一些實際案例來展示其用法和優勢。 #### 12.1 使用 Lambda 表達式進行事件處理 在 GUI 編程中&#xff0c;事件處理是一個常見的任務。使用 Lambda 表達式可以簡化事件處理代碼…

Nginx主配置文件---Nginx.conf

nginx主配置文件的模塊介紹 全局塊&#xff1a; 全局塊是配置文件從開始到 events 塊之間的部分&#xff0c;其中指令的作用域是 Nginx 服務器全局。主要指令包括&#xff1a; user&#xff1a;指定可以運行 Nginx 服務的用戶和用戶組&#xff0c;只能在全局塊配置。例如&…

軟考《信息系統運行管理員》-2.2 信息系統運維的組織

2.2 信息系統運維的組織 信息系統運維的任務 數據資源管理 數據收集、數據校驗、數據錄入、數據處理 軟件資源管理 采購、保存、相關文檔保管、分發、安裝、支持、評價、培訓 硬件資源管理 檢查、維護、故障處理、更新、修復、擴充 系統安全管理 可用性、完整性、保密性、可控…

USB PD+TYPE -C快充電源中MOSFET選型,USB PD應用市場包含智能手機,平板電腦,筆記本電腦,游戲本,移動硬盤,數碼相機,電動工具等傳統領域

USB PD全稱為USB Power Delivery&#xff0c;是由USB-IF組織制定的一種快速充電協議&#xff0c;也是目前市場非常看好的一種協議&#xff0c;可以支持輸出功率高達100W&#xff1b;Type-C是一種接口規范&#xff0c;能夠支持傳輸更大的電流。USB PD應用市場不僅包含智能手機&a…