【算法】歸并排序

算法系列七:歸并排序

一、歸并排序的遞歸探尋

1.思路

2.搭建

2.1設計過掉不符情況(在最底層時)

2.2查驗能實現基礎排序(在最底層往上點時)

2.3跳轉結果繼續往上回搭

3.實質

4.實現

二、遞歸的調用棧

1.遞歸的執行過程

2.遞歸的函數棧幀

2.1遞歸函數的棧幀壓彈

2.2合并有序數組函數的棧幀壓彈

三、歸并排序的復雜度

1.空間復雜度

2.時間復雜度


一、歸并排序的遞歸探尋

1.思路

理想結果等于成分解斷開子結果表達式的公式表示

快速排序:

整個數組有序 = 其中一個元素有序 + 其左斷開數組有序 + 其右斷開數組有序

歸并排序

整個數組有序 = 左斷開數組有序 + 右斷開數組有序 + 兩有序數組的有序合并


2.搭建

2.1設計過掉不符情況(在最底層時)

  • if(array == null) return, 數組沒有元素不用排,下面是有元素
  • if(left == right) return,只有一個元素已經是有序了不用排,下面是多個元素
  • if(left > right) return,排不了不要排的,之后下面是符合一般情況的多個元素?

2.2查驗能實現基礎排序(在最底層往上點時)

在最底層往上點時,有序數組有序合并操作在最底層能實現兩元素之間的比較然后進行排序的


2.3跳轉結果繼續往上回搭:

跳轉有序數組結果繼續往上有序合并維護回搭


3.實質

從底層的最小單個斷開有序數組往上有序地合并成越來越大的斷開有序數組直至合并完成一個整體的有序數組


4.實現

    public static void mergeSort(int[] array) {mergeSortFunc(array,0,array.length-1);}private static void mergeSortFunc(int[] array,int left,int right) {if(left >= right) return;int mid = (left+right) / 2;mergeSortFunc(array,left,mid);mergeSortFunc(array,mid+1,right);merge(array,left,right,mid);}private static void merge(int[] array, int left, int right, int mid) {int s1 = left;int s2 = mid+1;int[] tmpArr = new int[right-left+1];int k = 0;//證明兩個區間 都同時有數據的while (s1 <= mid && s2 <= right) {if(array[s2] <= array[s1]) {tmpArr[k++] = array[s2++];}else {tmpArr[k++] = array[s1++];}}while (s1 <= mid) {tmpArr[k++] = array[s1++];}while (s2 <= right) {tmpArr[k++] = array[s2++];}//tmpArr 里面一定是這個區間內有序的數據了for (int i = 0; i < tmpArr.length; i++) {array[i+left] = tmpArr[i];}}

二、遞歸的調用棧

1.遞歸的執行過程

在函數遞歸中,調用的函數里面執行著再調用著隨著形參深入的不斷變化的函數自己

第一次調用函數的執行轉去等著第二次調用函數的執行完,第二次調用函數的執行也卡著轉去等第三次調用函數的執行完,一層層形參變化著重復地執行調用而都沒有往下去return直到最后調用函數傳的形參變化到符合return的條件不再繼續往下調用了return出結果開始往回地一層層促進上一層沒有執行完到執行完return,即開始往回地執行往回地歸


2.遞歸的函數棧幀

所有任意一個函數的調用都會獨立開辟新的函數棧幀(里面存放局部變量、函數形參、返回地址、寄存器值)壓入調用棧中,在函數執行到return語句結束后才彈出棧

遞歸調用時,函數棧幀從先往后地一個個獨立地壓入棧中,往下遞歸直到形參條件變到return由最新函數調用的棧幀開始往上彈棧幀出調用棧,在開始往上彈出棧幀開始有執行完往回層往下執行時,方法里面有可能寫的是繼續又去執行調用當前層形參條件下的再來一波函數遞歸調用(形參變化可能就去設置成不同的了就會是左右不一樣的分支),即是二叉即二叉樹的情況:

  • 每一層不僅要左邊往下全執行到底層然后開始往上全執行到它那層的左邊結束,接著又要執行右邊的往下執行到底層然后再往上全執行完到它的右層結束最后它這個節點對應的這層函數才也執行完它的棧幀也彈出調用棧,二叉樹從大到小所有的結構都是左邊往下全執行完往上回來、右邊往下全執行完往上回來、接著它這個節點的棧幀也往上彈返回執行完?

2.1遞歸函數的棧幀壓彈

在歸并排序的二叉樹遞歸調用過程中:

  1. 每次累計著往下調用到底層時,此時的調用棧所占的空間是最大的、深度在二叉樹的最底層,調用棧的空間計算為調用棧里棧幀的個數×每個棧幀的內存大小,在每個函數的棧幀中,函數里面那些函數的調用信息并非循環出現的常量個數的局部變量空間和都可算成常數的大小,所以在歸并排序這里,調用棧的最大空間為在調用棧里棧幀個數最多的時候:樹的高度log(n)*每個函數棧幀的內存大小是常數,即log(n)*常數函數調用執行完最底層后就開始有往上返回了,往上彈出最新最頂的棧幀
  2. 然后執行完返回到上層時又回到當前層條件下的且新的形參變化模式的再往下遞歸,又會去壓棧到最底層,此時調用棧的空間又達到最大的log(n)
  3. 當它右邊往下的也全執行完又往上返回到當前層時,就開始繼續往下接著執行就開始有去調用合并有序數組的函數了

2.2合并有序數組函數的棧幀壓彈

執行調用合并有序數列的函數時,調用棧又會壓入合并有序數組函數的棧幀,里面存放有開辟的當前層數組元素個數大小的數組(非常量級的,要算的),此時總的占用空間為調用棧的空間log(n-...)+n(-...),因為合并有序數組函數的棧幀每次都是處在棧頂壓入的函數里面并沒有再調用函數的在它之上再壓棧,所以它每次在棧頂進來壓棧完就緊接著彈出棧的


三、歸并排序的復雜度

1.空間復雜度

空間復雜度計算的是整個執行所有時刻中出現的最大瞬時占用空間

從下層往上層的返回的過程中,遞歸函數的調用棧空間變小著、合并有序數組的函數棧幀在變大著(里面的數組越來越大的):

  • 最底層時占用的空間為遞歸函數的調用棧空間log(n)+合并有序數組的函數棧幀0,即log(n)+0=log(n)
  • 當到達最上層第一層時,遞歸函數的調用棧空間是1,而合并有序數組的函數棧幀空間是n,此時的總空間大小是n,相比于最底層的log(n)及從下往上的過程中log(n)的遞減、n的遞增的總空間,此時的n是整個執行所有時刻中出現的最大瞬時占用的空間,所以歸并排序的空間復雜度是O(n)


2.時間復雜度

時間復雜度即算整個遞歸調用執行過程的時間和,我們可以不用按著遞歸搜索的過程去時時累計總的算,直接站在總二叉樹的角度一層一層地算所有時間的和就行了一層層里面每一個樹節點及下的全執行完對應著該調用函數的全執行完,因為遞歸調用語句mergeSortFunc(array,left,mid)都是且已轉成里面的函數節點內容來算了(調用中的去執行調用部分是常量級的已不算),且if(left >= right) return、int mid = (left+right) / 2也都是常量級的執行時間不算對應到總的時間就是計算所有函數節點里的merge(array,left,right,mid)合并有序數組的時間和每一層所有函數節點的合并有序數組時間和都為n(除了最后一層的函數節點進去就直接判斷為return沒執行有序數組合并),一共有log(n)層,所以時間復雜度為O(n*log(n))?

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

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

相關文章

線束線纜從二維設計到虛擬驗證全流程解決方案

一、傳統設計中的痛點 線纜的開發設計是橫跨多專業多學科的龐大工程&#xff0c;通常會劃分為幾大階段逐次推進&#xff0c;由于每個階段的工作任務不同&#xff0c;所以在不同設計階段使用的工具也完全不同&#xff0c;由此導致整個設計流程中工程師常常要跨平臺協作&#xf…

【智駕中的大模型 -1】自動駕駛場景中的大模型

1. 前言 我們知道&#xff0c;大模型現在很火爆&#xff0c;尤其是 deepseek 風靡全球后&#xff0c;大模型毫無疑問成為為中國新質生產力的代表。百度創始人李彥宏也說&#xff1a;“2025 年可能會成為 AI 智能體爆發的元年”。 隨著科技的飛速發展&#xff0c;大模型的影響…

個人博客系統后端 - 注冊登錄功能實現指南

一、功能概述 個人博客系統的注冊登錄功能包括&#xff1a; 用戶注冊&#xff1a;新用戶可以通過提供用戶名、密碼、郵箱等信息創建賬號用戶登錄&#xff1a;已注冊用戶可以通過用戶名和密碼進行身份驗證&#xff0c;獲取JWT令牌身份驗證&#xff1a;使用JWT令牌訪問需要認證…

投行交易與風控系統的消費側冪等架構設計與實戰

1.背景和痛點 1.1 資金操作敏感性場景 核心需求&#xff1a; 交易唯一性&#xff1a;資金類操作必須保證全局唯一執行計算原子性&#xff1a;風控指標計算需具備事務性特征審計追溯&#xff1a;所有操作需保留完整冪等軌跡 1.2 業務損失統計 二、技術挑戰與架構設計 2.1 分…

odoo-046 視圖顯示的 name 數據庫中存儲的不一樣

文章目錄 一、問題由來二、排查經過1. 問 deepseek2. 驗證3. 新問題 三、 總結四、補充&#xff08;翻譯模型 ir.translation 中 src 和 value 字段詳解&#xff09; 一、問題由來 客戶有多個公司&#xff0c;使用多個數據庫。他們有時需要同步不同數據庫之間的數據的需求。在…

充電寶項目:規則引擎Drools學習

文章目錄 規則引擎 Drools1 問題2 規則引擎概述2.1 規則引擎2.2 使用規則引擎的優勢2.3 規則引擎應用場景2.4 Drools介紹 3 Drools入門案例3.1 創建springboot項目 引入依賴3.2 添加Drools配置類3.4 創建實體類Order3.5 orderScore.drl3.6 編寫測試類 4 Drools基礎語法4.1 規則…

HTML、CSS 和 JavaScript 常見用法及使用規范

一、HTML 深度剖析 1. 文檔類型聲明 HTML 文檔開頭的 <!DOCTYPE html> 聲明告知瀏覽器當前文檔使用的是 HTML5 標準。它是文檔的重要元信息&#xff0c;能確保瀏覽器以標準模式渲染頁面&#xff0c;避免怪異模式下的兼容性問題。 2. 元數據標簽 <meta> 標簽&am…

基于CNN+ViT的蔬果圖像分類實驗

本文只是做一個簡單融合的實驗&#xff0c;沒有任何新穎&#xff0c;大家看看就行了。 1.數據集 本文所采用的數據集為Fruit-360 果蔬圖像數據集&#xff0c;該數據集由 Horea Mure?an 等人整理并發布于 GitHub&#xff08;項目地址&#xff1a;Horea94/Fruit-Images-Datase…

Ubuntu24.04安裝libgl1-mesa-glx 報錯,軟件包缺失

在 Ubuntu 24.04 系統中&#xff0c;您遇到的 libgl1-mesa-glx 軟件包缺失問題可能是由于該包在最新的 Ubuntu 版本中被重命名為 libglx-mesa0。以下是針對該問題的詳細解決方案&#xff1a; 1. 問題原因分析 包名稱變更&#xff1a;在 Ubuntu 24.04 中&#xff0c;libgl1-me…

webpack vite

? 1、webpack webpack打包工具&#xff08;重點在于配置和使用&#xff0c;原理并不高優。只在開發環境應用&#xff0c;不在線上環境運行&#xff09;&#xff0c;壓縮整合代碼&#xff0c;讓網頁加載更快。 前端代碼為什么要進行構建和打包&#xff1f; 體積更好&#x…

如何在爬蟲中合理使用海外代理?在爬蟲中合理使用海外ip

我們都知道&#xff0c;爬蟲工作就是在各類網頁中游走&#xff0c;快速而高效地采集數據。然而如果目標網站分布在多個國家或者存在區域性限制&#xff0c;那靠普通的網絡訪問可能會帶來諸多阻礙。而這時&#xff0c;“海外代理”儼然成了爬蟲工程師們的得力幫手&#xff01; …

數據倉庫分層存儲設計:平衡存儲成本與查詢效率

數據倉庫分層存儲不僅是一個技術問題,更是一種藝術:如何在有限的資源下,讓數據既能快速響應查詢,又能以最低的成本存儲? 目錄 一、什么是數據倉庫分層存儲? 二、分層存儲的體系架構 1. 數據源層(ODS,Operational Data Store) 2. 數據倉庫層(DW,Data Warehouse)…

YOLO學習筆記 | 基于YOLOv8的植物病害檢測系統

以下是基于YOLOv8的植物病害檢測系統完整技術文檔,包含原理分析、數學公式推導及代碼實現框架。 基于YOLOv8的智能植物病害檢測系統研究 摘要 針對傳統植物病害檢測方法存在的效率低、泛化性差等問題,本研究提出一種基于改進YOLOv8算法的智能檢測系統。通過設計輕量化特征提…

高級語言調用C接口(二)回調函數(4)Python

前面2篇分別說了java和c#調用C接口&#xff0c;參數為回調函數&#xff0c;回調函數中參數是結構體指針。 接下來說下python的調用方法。 from ctypes import * import sysclass stPayResult(Structure):_pack_ 4 # 根據實際C結構體的對齊方式設置&#xff08;常見值為1,4,…

springboot啟動動態定時任務

1.自定義定時任務線程池 package com.x.devicetcpserver.global.tcp.tcpscheduler;import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotatio…

pytorch框架認識--手寫數字識別

手寫數字是機器學習中非常經典的案例&#xff0c;本文將通過pytorch框架&#xff0c;利用神經網絡來實現手寫數字識別 pytorch中提供了手寫數字的數據集&#xff0c;我們可以直接從pytorch中下載 MNIST中包含70000張手寫數字圖像&#xff1a;60000張用于訓練&#xff0c;10000…

WPF 使用依賴注入后關閉窗口程序不結束

原因是在ViewModel中在構造函數中注入了Window 對象&#xff0c;即使沒有使用&#xff0c;主窗口關閉程序不會退出&#xff0c;即使 ViewModel 是 AddTransient 注入的。 解決方法&#xff1a;不使用構造函數注入Window&#xff0c;通過GetService獲取Window 通過注入對象調用…

用戶管理(添加和刪除,查詢信息,切換用戶,查看登錄用戶,用戶組,配置文件)

目錄 添加和刪除用戶 查詢用戶信息 切換用戶 查看當前的操作用戶是誰 查看首次登錄的用戶是誰 用戶組&#xff08;對屬于同個角色的用戶統一管理&#xff09; 新增組 刪除組 添加用戶的同時&#xff0c;指定組 修改用戶的組 組的配置文件&#xff08;/etc/group&…

PyTorch學習-小土堆教程

網絡搭建torch.nn.Module 卷積操作 torch.nn.functional.conv2d(input, weight, biasNone, stride1, padding0, dilation1, groups1) 神經網絡-卷積層

MVCC詳細介紹及面試題

目錄 1.什么是mvcc&#xff1f; 2.問題引入 3. MVCC實現原理&#xff1f; 3.1 隱藏字段 3.2 undo log 日志 3.2.1 undo log版本鏈 3.3 readview 3.3.1 當前讀 ?編輯 3.3.2 快照讀 3.3.3 ReadView中4個核心字段 3.3.4 版本數據鏈訪問的規則&#xff08;了解&#x…