網站首頁 編程語言 正文
hello??
昨天發了個堆排序,竟然上了熱榜
所以,今天來發一下歸并排序
上次的堆排序似乎好多人沒看懂,其實這些還是比較基礎滴??
廢話不多說,直接進入正題
分治算法
如果你要學歸并排序,首先你要學一下分治
所謂分治,就是分開治理,把大問題化成小問題,逐個解決,再合到一起
這也就是歸并排序的精髓
這種算法時間復雜度低,原理也比較簡單
歸并排序
首先來看這張圖
圖片中把一個數組分成了一個一個的元素,在合并的過程中排序
怎么分
分的方法其實很簡單,一個遞歸就可以解決
如果你是初學者,可能沒有完全把遞歸學透徹
簡單說,遞歸就是在函數內部調用自己的函數
遞歸都要有一個出口,否則就會變成死循環
遞歸的出口
我們在函數參數上寫1)一個數組(要被排序的數組)2)分的開始和結束(first和end)
如果first<end,那么我們可以繼續遞歸,如果不滿足條件,遞歸結束
還要定義一個中間,前面那行代碼是分左邊,也就是開始~中間,后面那行代碼是分右邊,也就是中間+1~末尾
void merge_sort(int array[],int first,int end) { if(first < end){ int center = (first + end)/2; //得到中間數 merge_sort(array,first,center); merge_sort(array,center+1,end); } }
“并”的實現
按照上面的圖片,我們每排一下序就給它并一下
具體代碼實現
void merge(int array[],int first,int center,int end) { int n1 = center - first + 1; int n2 = end - center; int L[n1+1]; int R[n2+1]; for(int i = 0; i < n1; i++ ) { L[i] = array[first+i]; //得到前面一部分數組 } //printArray(L,n1); for(int j = 0; j < n2; j++ ) { R[j] = array[center+j+1]; //得到后面一部分數組 } //printArray(R,n2); L[n1] = 1000; //設置哨兵 R[n2] = 1000; //設置哨兵 //cout << "R[5] =" << R[4] << endl; int k1 = 0; int k2 = 0; for (int k = first; k <= end; ++k) //把得到的兩個數組進行排序合并 { //cout << L[k1] <<endl; //cout << R[k2] <<endl; if(L[k1] <= R[k2]) { //cout << L[k1] <<endl; array[k] = L[k1]; //cout << array[k] << endl; //cout << "k1 =" << k1 << endl; k1 = k1 + 1; }else{ //cout << R[k2] <<endl; array[k] = R[k2]; //cout << array[k] << endl; //cout << "k2 =" << k2 << endl; k2 = k2 + 1; } //cout << array[k] <<endl; } //printArray(array,10); }
加到“分”函數里
因為我們分完了要并,所以我們把“并”函數寫進“分”函數里
void merge_sort(int array[],int first,int end) { if(first < end){ int center = (first + end)/2; //得到中間數 merge_sort(array,first,center); merge_sort(array,center+1,end); merge(array,first,center,end); } }
完整代碼
加上int main()就行
#include <iostream> using namespace std; /* * 打印數組 */ void printArray(int array[],int length) { for (int i = 0; i < length; ++i) { cout << array[i] << endl; } } /* * 一個數組從中間分成兩個有序數組 * 把這兩個有序數組合并成一個有序數組 */ void merge(int array[],int first,int center,int end) { int n1 = center - first + 1; int n2 = end - center; int L[n1+1]; int R[n2+1]; for(int i = 0; i < n1; i++ ) { L[i] = array[first+i]; //得到前面一部分數組 } //printArray(L,n1); for(int j = 0; j < n2; j++ ) { R[j] = array[center+j+1]; //得到后面一部分數組 } //printArray(R,n2); L[n1] = 1000; //設置哨兵 R[n2] = 1000; //設置哨兵 //cout << "R[5] =" << R[4] << endl; int k1 = 0; int k2 = 0; for (int k = first; k <= end; ++k) //把得到的兩個數組進行排序合并 { //cout << L[k1] <<endl; //cout << R[k2] <<endl; if(L[k1] <= R[k2]) { //cout << L[k1] <<endl; array[k] = L[k1]; //cout << array[k] << endl; //cout << "k1 =" << k1 << endl; k1 = k1 + 1; }else{ //cout << R[k2] <<endl; array[k] = R[k2]; //cout << array[k] << endl; //cout << "k2 =" << k2 << endl; k2 = k2 + 1; } //cout << array[k] <<endl; } //printArray(array,10); } /* * 分治算法 * 把一個數組從中間分成分開 * 然后進行排序 */ void merge_sort(int array[],int first,int end) { if(first < end){ int center = (first + end)/2; //得到中間數 merge_sort(array,first,center); merge_sort(array,center+1,end); merge(array,first,center,end); } } int main(int argc, char const *argv[]) { int array[10] = {0,6,1,2,3,7,8,9,4,5}; //merge(array,0,4,9); merge_sort(array,0,9); printArray(array,10); //int center = (0 + 9)/2; //cout << "center" << center << endl; //cout << "hello"; return 0; }
原文鏈接:https://blog.csdn.net/m0_64036070/article/details/123802517
相關推薦
- 2022-12-26 C語言實現十六進制轉換為十進制的方法詳解_C 語言
- 2021-12-16 el-tree 設置選項框選中狀態,通過setCheckedKeys設置,會導致父選項框選中,子選項
- 2022-09-05 Verilog 之并行,數據類型,操作符號等相關基礎歸納
- 2022-10-12 pandas學習之df.fillna的具體使用_python
- 2023-07-02 Python+streamlit實現輕松創建人事系統_python
- 2022-10-26 jQuery中DOM?屬性使用實例詳解下篇_jquery
- 2023-01-12 C語言求字符串長度的四種方法實例代碼_C 語言
- 2022-07-24 C++深入刨析類與對象的使用_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支