归并排序和快速排序的两种实现

news2024/11/15 21:49:15

在此之前我们已经介绍过归并排序和快速排序:浅谈归并排序与快速排序,但其中的实现都是基于递归的。本文将重新温故这两种算法并给出基于迭代的实现。

目录

  • 1. 归并排序
    • 1.1 基于递归
    • 1.2 基于迭代
  • 2. 快速排序
    • 2.1 基于递归
    • 2.2 基于迭代

1. 归并排序

1.1 基于递归

归并排序的核心是二路归并,实现二路归并需要一个额外的辅助数组,因此空间复杂度是 O ( n ) O(n) O(n)

void merge(vector<int>& a, int l, int mid, int r, vector<int>& tmp) {
    int i = l, j = mid + 1, k = l;

    while (i <= mid && j <= r) {
        if (a[i] <= a[j]) tmp[k++] = a[i++];
        else tmp[k++] = a[j++];
    }

    while (i <= mid) tmp[k++] = a[i++];
    while (j <= r) tmp[k++] = a[j++];

    for (int i = l; i <= r; i++) a[i] = tmp[i];
}

该函数会对数组 a[l, mid][mid + 1, r] 两部分进行二路归并,其中辅助数组 tmp 的大小与 a 相同。

有了 merge 函数,我们就可以很方便的实现归并排序了:

void merge_sort(vector<int>& a, int l, int r, vector<int>& tmp) {
    if (l >= r) return;

    int mid = l + r >> 1;
    merge_sort(a, l, mid, tmp), merge_sort(a, mid + 1, r, tmp);

    merge(a, l, mid, r, tmp);
}

1.2 基于迭代

很明显,基于递归的实现是自顶向下的,而基于迭代的实现是自底向上的。

我们可以先枚举区间长度,再枚举区间左端点。一开始每个区间的长度是 1 1 1,我们每次对相邻的两个区间进行二路归并,每归并一次区间的长度就是原先的两倍,所以枚举区间长度时变量 len 的更新方式为 len *= 2

对于区间左端点,每合并完两个区间后,左端点就要更新成下下个区间,如下图所示:

还需保证 mid < n - 1,即 l < n - len

void merge_sort(vector<int>& a) {
    int n = a.size();
    vector<int> tmp(n);

    for (int len = 1; len < n; len *= 2) {
        for (int l = 0; l < n - len; l += 2 * len) {
            int mid = l + len - 1;
            int r = min(l + 2 * len - 1, n - 1);
            merge(a, l, mid, r, tmp);
        }
    }
}

归并排序的时间复杂度是 O ( n log ⁡ n ) O(n\log n) O(nlogn),无论是递归还是迭代,空间复杂度都是 O ( n ) O(n) O(n)

2. 快速排序

2.1 基于递归

void quick_sort(vector<int>& a, int l, int r) {
    if (l >= r) return;

    int mid = l + r >> 1;
    int i = l - 1, j = r + 1, x = a[mid];

    while (i < j) {
        while (a[++i] < x);
        while (a[--j] > x);
        if (i < j) swap(a[i], a[j]);
    }

    quick_sort(a, l, j), quick_sort(a, j + 1, r);
}

2.2 基于迭代

void quick_sort(vector<int>& a, int l, int r) {
    if (l >= r) return;

    stack<pair<int, int>> stk;
    stk.emplace(l, r);

    while (!stk.empty()) {
        auto [l, r] = stk.top();
        stk.pop();

        if (l < r) {
            int mid = l + r >> 1;
            int i = l - 1, j = r + 1, x = a[mid];
            while (i < j) {
                while (a[++i] < x);
                while (a[--j] > x);
                if (i < j) swap(a[i], a[j]);
            }
            stk.emplace(l, j);
            stk.emplace(j + 1, r);
        }
    }
}

时间复杂度是 O ( n log ⁡ n ) O(n\log n) O(nlogn),空间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/987898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

github网站打不开,hosts文件配置

首先获取github官网的ip地址&#xff0c; 打开cmd&#xff0c;输入ping github.com 配置&#xff1a; #github 140.82.114.4 github.com 199.232.69.194 github.global.ssl.fastly.net 185.199.108.153 assets-cdn.github.com 185.199.110.153 assets-cdn.github.com 185.199…

RT7625E两级电液伺服阀放大器

RT6215M、RT6225M、RT7625M、RT7625E、RTJ01、RT7325M双喷挡式两级电液伺服阀适合对位置、力和速度进行闭环控制&#xff0c;分体式比例放大器&#xff0c;无摩擦双喷嘴-挡板控制级&#xff0c;动态响应高&#xff0c;高分辨率&#xff0c;低滞环&#xff0c;干式力矩马达的二级…

windows10使用wheel安装tensorflow2.13.0/2.10.0

安装过程 安装虚拟环境安装virtualenv安装满足要求的python版本使用virtualenv创建指定python版本的虚拟环境 安装tensorflow2.13.0安装tensorflow-docs直接下载使用wheel下载 在VSCode编辑器中使用虚拟环境下的包 安装虚拟环境 这里笔者使用的是 virtualenv进行虚拟环境搭建的…

【linux基础(1)】

目录 一.linux的特殊结构二.命令简介及其格式三.ls命令四.cd和pwd命令简介1.cd命令2.pwd命令3.小结 五.绝对路径和相对路径六.特殊路径符 一.linux的特殊结构 linux的目录结构是一个树形结构 windows系统可以拥有多个盘符&#xff0c;如c盘&#xff0c;D盘&#xff0c;E盘 lin…

【C++】C++动态内存管理

&#x1f3f3;️‍&#x1f308;C/C内存分布 说明&#xff1a; 1.我们的代码并非放在代码段里的&#xff0c;而是以文件的形式存在磁盘上的。 代码经过编译链接形成的二进制指令&#xff0c;才是放进代码段里的。&#xff08;即可执行代码&#xff09; 2.“abcd”如果没有被c…

Ubuntu系统重装nvidia gpu驱动

1. 卸载原驱动 sudo apt remove *cuda* sudo apt remove *nvidia* sudo /usr/bin/nvidia-uninstall sudo dpkg -l | grep ^rc | cut -d -f3 | sudo xargs dpkg --purge sudo rm -rf ~/.cuda-license-* sudo apt purge nvidia-cuda-toolkit sudo apt remove nvidia-driver-* s…

无涯教程-JavaScript - IMABS函数

描述 IMABS函数以x yi或x yj文本格式返回复数的绝对值(模)。 Excel中的复数 复数简单地以文本形式存储在Excel中。 当将格式为" a bi"或" a bj"的文本字符串提供给Excel的内置复数函数之一时,这被解释为复数。 复数函数可以接受简单数值,因为它等效…

【面试心得】系统调用

这个问题也是在九识面试的时候被问到的&#xff0c;当时我说就是像Shell&#xff0c;从用户态转移到内核态的过程&#xff0c;面试官让我说的详细一点&#xff0c;我就说不出来了&#xff0c;然后我就说了一些函数调用的过程&#xff0c;hhhh。 现在在这里做一个记录吧。 本文…

已经2023年了,你还不会手撕轮播图?

目录 一、前言二、动画基础1. 定时器2. left与offsetLeft3. 封装函数3.1 物体3.2 目标点3.3 回调函数 4.封装 三、基础结构3.1 焦点图3.2 按钮3.3 小圆点3.4 总结 四、按钮显示五、圆点5.1 生成5.2 属性5.3 移动 六、按钮6.1 准备6.2 出错6.2.1 小圆点跟随6.2.2 图片返回 6.3 b…

【 OpenGauss源码学习 —— 列存储(analyze)(四)】

列存储&#xff08;analyze&#xff09; AcquireSampleCStoreRows 函数es_get_attnums_to_analyze 函数CStoreRelGetCUNumByNow 函数CStore::GetLivedRowNumbers 函数InitGetValFunc 函数CStoreGetfstColIdx 函数CStore::GetCUDesc 函数CStore::IsTheWholeCuDeleted 函数CStore…

学习Bootstrap 5的第七天

目录 徽章 徽章 实例 上下文徽章 实例 胶囊徽章 实例 元素内的徽章 实例 进度条 基础进度条 实例 进度条高度 实例 彩色进度条 实例 条纹进度条 实例 动画进度条 实例 混合色彩进度条 实例 徽章 徽章 在 Bootstrap 中&#xff0c;徽章&#xff08;Badg…

【动手学深度学习】--文本预处理

文章目录 文本预处理1.读取数据集2.词元化3.词表4.整合所有功能 文本预处理 学习视频&#xff1a;文本预处理【动手学深度学习v2】 官方笔记&#xff1a;文本预处理 对于序列数据处理问题&#xff0c;在【序列模型】中评估了所需的统计工具和预测时面临的挑战&#xff0c;这…

2023年8月| 红帽RHCE考试战报-微思红帽官方授权培训中心

2023.8.15 新出炉一波红帽考试战报 恭喜微思10位学员顺利PASS红帽认证考试 通过RHCE认证 不仅从专业技术上证明了你的能力 在职场上更是一块进入Linux行业的“敲门砖” 让你在职场竞争中更具竞争力 微思红帽官方授权培训中心--全国直播&#xff0c;就近安排考试&#xff…

【技巧】安装 win11 必须联网?无法跳过?

安装 Win11 时自动检查更新或者让连接网络&#xff0c;没有提供取消按钮&#xff0c;之前有【我没有 Internet 连接】选项。 在这个界面按 ShiftF10 打开命令提示符 输入OOBE\BYPASSNRO 按回车。 回车之后之后系统会重新启动&#xff0c;此时发现下一步的左侧出现了熟悉的【我…

Matlab论文插图绘制模板第112期—带阴影标记的图

之前的文章中&#xff0c;分享了Matlab带线标记的图&#xff1a; 进一步&#xff0c;本期分享的是带阴影标记的图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载。有需要的朋友可以关注同名公号…

MCP2515调试心得

基于 STM32 芯片的 MCP2515 芯片调试心得 1. MCP2515 芯片解析1.1 外部时钟源1.2 可采用连续传输提高效率发送数据时&#xff0c;使用 TX0 为例&#xff1a; 1.3 关于 MASK 和 Filter 的注意事项1.3.1 Filter 的注意事项1.3.2 MASK 设置的一些问题 2. STM32 硬件 SPI 问题 1. M…

外滩大会发布银行数字化5大趋势:随身银行、AI风控、数字员工、边缘物联与云原生

通用人工智能风起云涌&#xff0c;金融行业将如何应对&#xff1f; 9月8日&#xff0c;由中国银行业协会指导&#xff0c;网商银行承办的外滩大会银行业数字化论坛上&#xff0c;IDC中国副总裁兼首席分析师武连峰发布了《银行数字科技五大趋势》&#xff1a;随身银行、AI风控、…

ULN2003 芯片

芯片介绍&#xff1a; ULN2003 是高耐压、大电流达林顿陈列&#xff0c;由七个硅 NPN 达林顿管组成。 达林顿管并联可以承受更大的电流。 此电路主要应用于继电器驱动器&#xff0c;字锤驱动器&#xff0c;灯驱动器&#xff0c;显示驱动器&#xff08;LED 气 体放电&#…

Apache Tomcat 漏洞复现

文章目录 Apache Tomcat 漏洞复现1. Tomcat7 弱密码和后端 Getshell 漏洞1.1 漏洞描述1.2 漏洞复现1.3 漏洞利用1.3.1 jsp小马1.3.2 jsp大马 2. Aapache Tomcat AJP任意文件读取/包含漏洞2.1 漏洞描述2.1 漏洞复现2.2 漏洞利用工具 3. 通过 PUT 方法的 Tomcat 任意写入文件漏洞…

10元/月?中国电信推出手机直连卫星功能,华为联合开启卫星之旅

2021年9月8日&#xff0c;华为Mate 60 Pro 系列手机首次推出“卫星语音通话”功能。此功能需与运营商合作&#xff0c;而中国电信率先推出了“手机直连卫星”服务。 中国电信的用户可以在自己的普通手机卡套餐基础上&#xff0c;加装直连卫星服务。此项服务的价格如下&#xff…