網(wǎng)站首頁 編程語言 正文
算法思路
歸并排序是一種分治算法:首先將數(shù)組分成兩半,然后對(duì)每一半進(jìn)行歸并排序,最后將兩個(gè)有序的子數(shù)組合并,以得到最終的排序數(shù)組。為了簡(jiǎn)潔下面代碼中會(huì)調(diào)用 STL 的 i n p l a c e _ m e r g e inplace\_merge inplace_merge 方法,這個(gè)方法的作用正是將兩個(gè)連續(xù)的有序區(qū)間合并為一個(gè)有序區(qū)間,當(dāng)然也可以自己按合并有序鏈表的思路寫一個(gè) m e r g e merge merge 方法~
a. 遞歸
自頂向下的遞歸排序
void merge_sort(vector<int> &li, int s, int e) {//li[s,e)為待排序的子數(shù)組
if (e - s <= 1)
return;
int mid = (s + e) / 2;
merge_sort(li, s, mid);
merge_sort(li, mid, e);
inplace_merge(li.begin() + s, li.begin() + mid, li.begin() + e);//合并有序區(qū)間[s,mid)和[mid,e)
}
b. 棧模擬遞歸
用一個(gè)棧模擬遞歸排序中區(qū)間處理的過程,注意一個(gè)區(qū)間可能會(huì)在棧中出現(xiàn)兩次:第一次其兩個(gè)子區(qū)間還未排序,第二次其兩個(gè)子區(qū)間已經(jīng)有序,所以需要有一個(gè)額外的標(biāo)志位來區(qū)分一個(gè)區(qū)間在棧中的這兩種狀態(tài)。
void merge_sort_stack(vector<int> &li, int s, int e) {//li[s,e)為待排序的子數(shù)組
stack<tuple<int, int, int>> st;
st.emplace(s, e, 0);
while (!st.empty()) {
auto [l, r, tag] = st.top();//當(dāng)前區(qū)間為[l,r) , 標(biāo)志位為tag
st.pop();
if (tag == 0) {//當(dāng)前區(qū)間第一次出現(xiàn)
if (r - l <= 1)
continue;
int mid = (l + r) / 2;
st.emplace(l, r, 1);
st.emplace(l, mid, 0);
st.emplace(mid, r, 0);
} else {//當(dāng)前區(qū)間第二次出現(xiàn)
int mid = (l + r) / 2;
inplace_merge(li.begin() + l, li.begin() + mid, li.begin() + r);//合并有序區(qū)間[l,mid)和[mid,r)
}
}
}
c. 遞推
自底向上的遞推:首先兩兩一組的合并長為 2 0 2^0 20 的子數(shù)組,再兩兩一組的合并長為 2 1 2^1 21 的子數(shù)組, ? \cdots ? ,直到 2 k 2^k 2k 不小于數(shù)組長度時(shí)遞推結(jié)束。注意每一輪合并中最后一組的右邊的子數(shù)組的長度可能小于 2 k 2^k 2k。
void merge_sort(vector<int> &li, int s, int e) {//li[s,e)為待排序的子數(shù)組
int n = e - s;
for (int len = 1; len < n; len *= 2)//合并的子數(shù)組的長度len不超過n
for (int i = s; i + len < e; i += len * 2)//逐對(duì)枚舉兩個(gè)相鄰的子數(shù)組
inplace_merge(li.begin() + i, li.begin() + i + len, li.begin() + min(e, i + len * 2));//合并有序區(qū)間[i,i+len)和[i+len,min(e,i+len*2))
}
原文鏈接:https://blog.csdn.net/weixin_40519680/article/details/132906998
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2023-05-26 解讀tf.keras.layers模塊中的函數(shù)_python
- 2022-09-25 navicat連接遠(yuǎn)程服務(wù)器報(bào)錯(cuò)代碼:10038
- 2022-11-17 Android自定義一個(gè)view?ViewRootImpl繪制流程示例_Android
- 2022-05-20 快速安裝Docker詳細(xì)步驟教程_docker
- 2023-12-18 Redis的簡(jiǎn)單使用
- 2023-05-16 iOS開發(fā)藍(lán)牙技術(shù)應(yīng)用增加無線連接功能_IOS
- 2022-09-19 C語言數(shù)據(jù)結(jié)構(gòu)之單鏈表存儲(chǔ)詳解_C 語言
- 2023-07-05 parcel運(yùn)行終端報(bào)錯(cuò)Uncaught ReferenceError: parcelRequire
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支