【數據結構與算法】十大經典排序算法-歸并排序

🌟個人博客:www.hellocode.top
🏰Java知識導航:Java-Navigate
🔥CSDN:HelloCode.
🌞知乎:HelloCode
🌴掘金:HelloCode
?如有問題,歡迎指正,一起學習~~


當談到高效的排序算法時,歸并排序是一個備受推崇的選擇。歸并排序是一種分治算法,它將一個大問題分解成若干個小問題,然后逐個解決這些小問題,并將它們合并成一個整體的解。

基本思想

這里采用五分鐘學算法大佬的圖解,十分清晰

  1. 分解階段: 將待排序數組分成兩個相等或近似相等的子數組,不斷將問題規模縮小。
  2. 解決階段: 遞歸地對兩個子數組進行排序,直到子數組的長度為1(即已有序)。
  3. 合并階段: 將排好序的子數組合并成一個有序的數組,這是歸并排序的核心操作。

三個階段,涉及到遞歸就比較難理解(個人感覺),最好配合動畫好好理解理解。主要就是分解和歸并(將大問題分解為小問題,再通過歸并過程合并并排序)

代碼實現

每次隨便寫數組挺麻煩的,后續就都使用我寫的工具類來生成隨機數組了~

歸并排序相對難理解一些,主要涉及到分解和歸并,將待排序數組一個個拆分,直到拆分為1個1組(無需排序),接下來就是自底向上逐個合并,在合并的同時進行排序操作,最終合并好的就是有序的數組了

/*** @author HelloCode* @blog https://www.hellocode.top* @date 2023年08月15日 19:33*/
public class MergeSort {public static void main(String[] args) {// 生成容量為15的由100以內隨機數構成的int數組(用到了自己寫的一個工具類)int[] arr = ArrayUtil.randomIntArray(15, 100);System.out.println("原數組:" + Arrays.toString(arr));mergeSort(arr);System.out.println("排序后:" + Arrays.toString(arr));}private static void mergeSort(int[] arr) {if (arr == null || arr.length <= 1) {return; // 數組為空或只有一個元素,無需排序}// 創建臨時數組(避免多次創建)int[] temp = new int[arr.length];// 遞歸入口sort(arr, temp, 0, arr.length - 1);}// 拆分private static void sort(int[] arr, int[] temp, int left, int right) {// 遞歸出口if (left >= right) {return;}// 記錄中間值(左邊數組的末尾,+1為右邊數組的起始)int mid = left + ((right - left) >> 1);// 開始拆分sort(arr, temp, left, mid);sort(arr, temp, mid + 1, right);// 歸并merge(arr, temp, left, mid, right);}// 歸并(排序)private static void merge(int[] arr, int[] temp, int left, int mid, int right) {// 記錄臨時數組索引int p = left;// 左半邊起始索引int i = left;// 右半邊起始索引int j = mid + 1;// 開始歸并// 兩邊都還有的情況while(i <= mid && j <= right){if(arr[i] <= arr[j]){temp[p++] = arr[i++];}else{temp[p++] = arr[j++];}}// 左邊還有剩余的情況(直接加到臨時數組末尾)while(i <= mid){temp[p++] = arr[i++];}// 右邊還有剩余的情況(直接加到臨時數組末尾)while(j <= right){temp[p++] = arr[j++];}// 將臨時數組拷貝回原數組for(int k = left; k <= right; k++){arr[k] = temp[k];}}
}

測試:

原數組:[83, 49, 19, 75, 26, 64, 59, 60, 11, 97, 36, 41, 17, 31, 69]
排序后:[11, 17, 19, 26, 31, 36, 41, 49, 59, 60, 64, 69, 75, 83, 97]

生成隨機數組的工具類:

/*** @author HelloCode* @blog https://www.hellocode.top* @date 2023年08月13日 20:01*/
public class ArrayUtil {private static final Random RANDOM = new Random();public static int[] randomIntArray(int capacity,int max){// 創建capacity大小的數組(1~max)int[] res = new int[capacity];for(int i = 0; i < capacity; i++){res[i] = RANDOM.nextInt(max) + 1;}return res;}
}

優化

歸并排序本身是一個穩定且效率較高的排序算法,但還是有一些優化方法可以進一步提升性能:

  1. 插入排序優化: 對于小規模子數組,使用插入排序可以提高性能。當子數組長度小于一定閾值時,切換到插入排序可以減少遞歸調用開銷。
  2. 自底向上歸并: 在歸并階段,可以使用自底向上的方法,避免遞歸調用,從而減少棧空間的使用。
  3. 優化合并操作: 在合并階段,如果左子數組的最大元素小于右子數組的最小元素,可以直接跳過合并操作,因為兩個子數組已經有序。

總結

優點

  1. 歸并排序穩定且適用于各種數據類型。
  2. 具有穩定的時間復雜度O(n log n),適用于大規模數據排序。
  3. 分治思想使其易于理解和實現,同時也為優化提供了空間。

缺點

  1. 歸并排序需要額外的存儲空間來存儲臨時數組,空間復雜度較高。
  2. 在小規模數據排序時,性能稍遜于快速排序。

復雜度

  • 時間復雜度:平均情況、最好情況和最壞情況下的時間復雜度均為O(n log n)。
  • 空間復雜度:空間復雜度為O(n),需要額外的存儲空間來存儲臨時數組。

使用場景

  • 歸并排序適用于需要穩定排序的場景,對性能有一定要求。
  • 特別適合用于外部排序,如在磁盤上對大文件進行排序。

通過分治思想,歸并排序將排序問題分解為小問題,并通過合并操作將它們逐步解決,從而實現高效且穩定的排序。這使得歸并排序成為計算機科學中重要的算法之一。

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

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

相關文章

如何用輸入函數為數組賦值

在編寫程序時我們經常使用數組&#xff0c;而數組的大小可能是很大的但是我們并不需要為每個元素都自己賦值&#xff0c;我們可能會自定義輸入數組元素個數&#xff0c;我們應該如何實現通過輸入函數為數組賦值呢&#xff1f; 目錄 第一種&#xff1a; 第二種&#xff1a; 第一…

大數據bug-sqoop(二:sqoop同步mysql數據到hive進行字段限制。)

一&#xff1a;sqoop腳本解析。 #&#xff01;/bin/sh mysqlHost$1 mysqlUserName$2 mysqlUserPass$3 mysqlDbName$4 sql$5 split$6 target$7 hiveDbName$8 hiveTbName$9 partFieldName${10} inputDate${11}echo ${mysqlHost} echo ${mysqlUserName} echo ${mysqlUserPass} ec…

OpenCV之remap的使用

OpenCV中使用remap實現圖像的重映射。 重映射是指將圖像中的某一像素值賦值到指定位置的操作&#xff1a;g(x,y) f ( h(x,y) )&#xff0c; 在這里&#xff0c; g( ) 是目標圖像, f() 是源圖像, 而h(x,y) 是作用于 (x,y) 的映射方法函數。為了完成映射過程, 需要獲得一些插值為…

TypeError: a bytes-like object is required, not ‘str‘

raceback (most recent call last): File "D:\pycharmcode\client.py", line 12, in <module> tcp_socket.send(send_data) TypeError: a bytes-like object is required, not str 使用socket進行ubuntu與windows通信時&#xff0c;發送數據時報了以上錯…

LeetCode 面試題 01.04. 回文排列

文章目錄 一、題目二、C# 題解 一、題目 給定一個字符串&#xff0c;編寫一個函數判定其是否為某個回文串的排列之一。 回文串是指正反兩個方向都一樣的單詞或短語。排列是指字母的重新排列。 回文串不一定是字典當中的單詞。 點擊此處跳轉題目。 示例1&#xff1a; 輸入&…

CSS3:圖片邊框

簡介 圖片也可以作為邊框&#xff0c;以下是實例演示 注意 實現該效果必須添加border樣式&#xff0c;且必須位于border-image-socure之前否則不會生效 實例 <html lang"en"><head><style>p {width: 600px;margin: 200px auto;border: 30px soli…

maven工具-maven的使用-鏡像倉庫、本地倉、IDEA使用maven

Maven 一、為什么使用maven 添加第三方jar包jar包之間的依賴關系處理jar包之間的沖突獲取第三方jar包將項目拆分成多個工程模塊實現項目的分布式部署 二、maven簡介 ? Maven項目對象模型(POM)&#xff0c;可以通過一小段描述信息來管理項目的構建&#xff0c;報告和文檔的…

2023.8 - java - 對象和類

public class Dog {String breed;int size;String colour;int age;void eat() {}void run() {}void sleep(){}void name(){} } 一個類可以包含以下類型變量&#xff1a; 局部變量&#xff1a;在方法、構造方法或者語句塊中定義的變量被稱為局部變量。變量聲明和初始化都是在方…

基于STM32標準庫智能風扇設計

目錄 一&#xff0c;前言 二&#xff0c;系統方案選擇 三&#xff0c;實體展示 工程分類 四&#xff0c;相關代碼 PWM.c PWM.h AD.c AD.h 電機驅動程序 舵機驅動 一&#xff0c;前言 當今生活中&#xff0c;風扇已成為人們解暑的重要工具&#xff0c;然而使用風扇緩解…

CentOS系統環境搭建(九)——centos系統下使用docker部署項目

centos系統環境搭建專欄&#x1f517;點擊跳轉 關于Docker-compose安裝請看CentOS系統環境搭建&#xff08;三&#xff09;——Centos7安裝Docker&Docker Compose&#xff0c;該文章同樣收錄于centos系統環境搭建專欄。 Centos7部署項目 采用前后端分離的形式部署。使用Do…

【Sklearn】基于隨機梯度下降算法的數據分類預測(Excel可直接替換數據)

【Sklearn】基于隨機梯度下降算法的數據分類預測(Excel可直接替換數據) 1.模型原理2.模型參數3.文件結構4.Excel數據5.下載地址6.完整代碼7.運行結果1.模型原理 隨機梯度下降(Stochastic Gradient Descent,SGD)是一種優化算法,用于訓練模型的參數以最小化損失函數。在分…

QT學習筆記-QT5.15編譯及安裝谷歌拼音輸入法(QtInputMethod_GooglePinyin)

QT學習筆記-QT5.15編譯及安裝谷歌拼音輸入法&#xff08;QtInputMethod_GooglePinyin&#xff09; 0、背景1、環境2、下載QtInputMethod_GooglePinyin源碼3、使用MinGW64構建套件編譯3.1 編譯QtInputMethod_GooglePinyin源碼3.2、部署tgtsmlInputContextPlugin輸入法插件3.3、運…

Lombok注解在JSON化中,JSON生成額外生成字段問題

問題描述&#xff1a; 定義如下對象 Dataclass A{private String A;public String getC() {return "abab";}} 執行如下邏輯 Autowiredprivate ObjectMapper objectMapper;Testpublic void test4() throws Exception {A a new A();a.setA("a");System.ou…

分布式 - 服務器Nginx:一小時入門系列之負載均衡

文章目錄 1. 負載均衡2. 負載均衡策略1. 輪詢策略2. 最小連接策略3. IP 哈希策略4. 哈希策略5. 加權輪詢策略 1. 負載均衡 跨多個應用程序實例的負載平衡是一種常用技術&#xff0c;用于優化資源利用率、最大化吞吐量、減少延遲和確保容錯配置。?使用 nginx 作為非常有效的HT…

【MySQL】如何使用Shared-memory協議(Windows)連接MySQL數據庫

文章目錄 【MySQL】如何使用Shared-memory協議(Windows)連接MySQL數據庫連接MySQL的協議使用Shared-memory協議(Windows)連接MySQL步驟1&#xff1a;確認MySQL服務器已啟用Shared-memory連接啟動Shared-memory連接方法 步驟2&#xff1a;客戶端使用shared-memory連接MySQL服務器…

神經網絡基礎-神經網絡補充概念-55-為什么是ML策略

“ML策略”&#xff08;Machine Learning Strategies&#xff09;是指在解決機器學習問題時&#xff0c;采取的一系列方法、技巧和策略。選擇適當的ML策略對于獲得高質量的模型和結果非常重要。以下是為什么要考慮ML策略的一些原因&#xff1a; 問題適應性&#xff1a;不同的機…

2023 最新版網絡安全保姆級指南,從 0 基礎進階網絡攻防工程師

一、網絡安全學習的誤區 1.不要試圖以編程為基礎去學習網絡安全 不要以編程為基礎再開始學習網絡安全&#xff0c;一般來說&#xff0c;學習編程不但學習周期長&#xff0c;且過渡到網絡安全用到編程的用到的編程的關鍵點不多。一般人如果想要把編程學好再開始學習網絡安全往…

Vue實例生命周期中的所有鉤子函數

在 Vue 3 中&#xff0c;實例生命周期的鉤子函數被整合為了兩個主要的階段&#xff1a;Composition API 階段和 Options API 階段。下面是 Vue 3 中的所有生命周期鉤子函數&#xff1a; Composition API 階段&#xff1a; setup //在組件實例創建之前執行&#xff0c;用于設…

centos 之安裝 openssl 1.1.1報錯

源碼make時報錯&#xff0c;可能是系統的perl的版本太低問題。 [rootlocalhost ~]# cpan -a | grep Test::More Test::More 0.92 1.302171 EXODIST/Test-Simple-1.302171.tar.gz [rootlocalhost ~]# cpan -a | grep Text::Template [rootlocalhost ~]# …

Dockerfile小記(持續)

文章目錄 信息新建用戶服務重啟數據庫相關SSH無交互安裝auth.logssh開機自啟 Apache服務配置 信息 Alpine系統 新建用戶 useradd命令參考 RUN apk update \ && apk add shadow \&& useradd -m togie \&& echo togie:12345 | chpasswd \&& &…