归并排序三种常见写法

算法思路

归并排序是一种分治算法:首先将数组分成两半,然后对每一半进行归并排序,最后将两个有序的子数组合并,以得到最终的排序数组。为了简洁下面代码中会调用 STL 的 i n p l a c e _ m e r g e inplace\_merge inplace_merge 方法,这个方法的作用正是将两个连续的有序区间合并为一个有序区间,当然也可以自己按合并有序链表的思路写一个 m e r g e merge merge 方法~


a. 递归

自顶向下的递归排序

cpp 复制代码
void merge_sort(vector<int> &li, int s, int e) {//li[s,e)为待排序的子数组
    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);//合并有序区间[s,mid)和[mid,e)
}

b. 栈模拟递归

用一个栈模拟递归排序中区间处理的过程,注意一个区间可能会在栈中出现两次:第一次其两个子区间还未排序,第二次其两个子区间已经有序,所以需要有一个额外的标志位来区分一个区间在栈中的这两种状态。

cpp 复制代码
void merge_sort_stack(vector<int> &li, int s, int e) {//li[s,e)为待排序的子数组
    stack<tuple<int, int, int>> st;
    st.emplace(s, e, 0);
    while (!st.empty()) {
        auto [l, r, tag] = st.top();//当前区间为[l,r) , 标志位为tag
        st.pop();
        if (tag == 0) {//当前区间第一次出现
            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 {//当前区间第二次出现
            int mid = (l + r) / 2;
            inplace_merge(li.begin() + l, li.begin() + mid, li.begin() + r);//合并有序区间[l,mid)和[mid,r)
        }
    }
}

c. 递推

自底向上的递推:首先两两一组的合并长为 2 0 2^0 20 的子数组,再两两一组的合并长为 2 1 2^1 21 的子数组, ⋯ \cdots ⋯ ,直到 2 k 2^k 2k 不小于数组长度时递推结束。注意每一轮合并中最后一组的右边的子数组的长度可能小于 2 k 2^k 2k。

cpp 复制代码
void merge_sort(vector<int> &li, int s, int e) {//li[s,e)为待排序的子数组
    int n = e - s;
    for (int len = 1; len < n; len *= 2)//合并的子数组的长度len不超过n
        for (int i = s; i + len < e; i += len * 2)//逐对枚举两个相邻的子数组
            inplace_merge(li.begin() + i, li.begin() + i + len, li.begin() + min(e, i + len * 2));//合并有序区间[i,i+len)和[i+len,min(e,i+len*2))
}
相关推荐
云小逸25 分钟前
【Nmap 设备类型识别技术】整体概况
服务器·c语言·网络·c++·nmap
梯度下降中26 分钟前
求职面试中的线代知识总结
人工智能·线性代数·算法·机器学习
SmartBrain37 分钟前
OCR 模型在医疗场景的选型研究
人工智能·算法·语言模型·架构·aigc·ocr
梵刹古音38 分钟前
【C语言】 跳转语句
c语言·开发语言·算法
liu****1 小时前
29.路径类dp
c++·算法·acm
JMchen1231 小时前
Android计算摄影实战:多帧合成、HDR+与夜景算法深度剖析
android·经验分享·数码相机·算法·移动开发·android-studio
阿猿收手吧!1 小时前
【C++】C++模板特化:精准定制泛型逻辑
开发语言·c++·算法
智驱力人工智能1 小时前
货车走快车道检测 高速公路安全治理的工程实践与价值闭环 高速公路货车占用小客车道抓拍系统 城市快速路货车违规占道AI识别
人工智能·opencv·算法·安全·yolo·目标检测·边缘计算
喵手1 小时前
Python爬虫实战:电商实体消歧完整实战 - 从混乱店铺名到标准化知识库的工程化实现,一文带你搞定!
爬虫·python·算法·爬虫实战·零基础python爬虫教学·同名实体消除·从混乱店铺名到标准化知识库
C语言小火车1 小时前
Qt样式实现方式详解:六大方法全面解析
c语言·c++·qt·学习