每日算法——归并排序

什么是归并排序

归并排序是一种分治算法。它将数组不断地分成两半,对每一半进行排序,然后再将排序好的两半合并起来。通过不断重复这个过程,最终得到完全排序的数组。

归并排序的注意点

  • 空间复杂度:归并排序需要额外的与原始数组大小相同的临时空间来进行合并操作,这可能在一些内存受限的场景下需要特别注意。
  • 递归深度:在处理大规模数据时,可能会导致较深的递归调用,需要关注栈空间的使用情况,避免栈溢出。
  • 边界条件处理:在分割和合并过程中,要确保正确处理各种边界情况,如空数组、只有一个元素的数组等。
  • 性能优化:虽然归并排序性能较为稳定,但在实际应用中可以考虑根据具体情况进行一些优化,比如更高效的合并操作等。

归并排序

题目描述

运行代码

#include <iostream>
using namespace std;
const int N = 1e5 + 5;
int a[N], t[N];
void merge_sort(int q[], int l, int r)
{
    if (l >= r) return;
    int mid = l + r >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);
    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) 
        t[k++] = q[i++];
        else t[k++] = q[j++];
    while (i <= mid) 
    t[k++] = q[i++];
    while (j <= r)
    t[k++] = q[j++];
    for (i = l, j = 0; i <= r; i++, j++) 
    q[i] = t[j];
}
int main()
{
    int n;
    cin>>n;
    for (int i = 0; i < n; i++) 
    cin>>a[i];
    merge_sort(a, 0, n - 1);
    for (int i = 0; i < n; i++) 
    cout<<a[i]<<" ";
    return 0;
}

代码思路

  1. 定义常量N = 1e5 + 5 用于确定数组的最大长度,以适应最多10万级别的数据。

  2. 归并排序函数merge_sort

    • 输入参数为待排序数组q,以及排序区间的左右边界索引lr
    • l >= r时,说明区间内元素个数小于或等于1,无需排序,直接返回。
    • 计算中间点mid,递归地对左半区间[l, mid]和右半区间[mid+1, r]进行排序。
    • 使用临时数组t[]进行合并操作:设立两个指针ij分别指向左右子序列的起始位置,比较两个序列中的元素,将较小的元素放入t[]中,直至一个序列遍历完。接着,将剩余未遍历完的序列的剩余元素全部拷贝到t[]中。
    • 最后,将t[]中的元素拷贝回原数组q[]中。
  3. 主函数:读取数组长度n和每个元素的值。调用merge_sort函数对数组进行排序。输出排序后的数组。

优化建议

  1. 减少临时数组的频繁创建:在当前代码中,每次递归调用merge_sort时都会创建和销毁临时数组t[],这在大数组排序时会消耗大量时间和空间。可以在函数外部定义一个全局的临时数组,避免每次递归都创建新数组。

  2. 非递归实现:对于极深的递归调用可能导致栈溢出的问题,可以考虑使用迭代而非递归的方式来实现归并排序,通过栈来管理待合并的区间,减少递归调用的深度。

  3. 尾递归优化:虽然C++标准没有强制规定编译器必须进行尾递归优化,但在理论上,如果编译器支持,可以通过修改递归调用的方式(在函数末尾调用自身,并且不需要在调用之后做其他操作)来实现。不过,归并排序的自然逻辑不太容易直接应用尾递归。

  4. 并行化:对于非常大的数据集,可以考虑将数组分割成多个部分,使用多线程或多进程分别排序,最后合并结果。这要求对归并过程进行适当的同步控制,以确保正确性。

其他代码(分治)

#include<iostream>
using namespace std;
const int N=1e5+5;
int a[N],temp[N];
void sortt(int a[],int l,int r){
    if (l >= r) { // 添加边界检查
        return;
    }
    int mid = (l + r) >> 1;
    sortt(a, l, mid);
    sortt(a, mid + 1, r);
    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r) {
        if (a[i] <= a[j]) {
            temp[k++] = a[i++];
        } else {
            temp[k++] = a[j++];
        }
    }
    while (i <= mid) {
        temp[k++] = a[i++];
    }
    while (j <= r) {
        temp[k++] = a[j++];
    }
    for (i = l, j = 0; i <= r; i++, j++) {
        a[i] = temp[j];
    }
    return;
}
int main() {
    int n;
    if (cin >> n) { // 检查输入是否成功
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        sortt(a, 0, n - 1);
        for (int i = 0; i < n; i++) {
            cout << a[i] <<'';
        }
    } 
    return 0;
}

代码思路

整体流程

  • 定义了一个常量 N 表示数组可能的最大长度。
  • 在 sortt 函数中实现归并排序的核心逻辑。
  • 在 main 函数中获取输入的数组长度 n ,并读取数组元素,然后调用 sortt 函数进行排序,最后输出排序后的结果。

归并排序的具体思路

  • sortt 函数通过不断地将数组区间一分为二,对分割后的两部分分别递归调用自身进行排序。
  • 在合并阶段,通过两个指针 i 和 j 分别遍历左右已排序的两部分。比较两个指针所指向元素的大小,将较小的元素放入临时数组 temp 中,并相应地移动指针。
  • 当左右两部分中的某一部分遍历完后,将另一部分剩余元素直接添加到临时数组后面。
  • 最后将临时数组中的排序好的元素复制回原数组对应的位置。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第1章Hello world 5/5:Rust/Java/C++实现Hello world代码优劣势对比:运行第一个程序

讲动人的故事,写懂人的代码 1.8 对比三种语言的Hello world代码特点和优劣势 艾极思又对比了三种语言的Hello world代码。 1.8.1 Rust的Hello world代码解读 让我们详细解释一下 Rust 这一个文件中的代码,并讨论为什么使用这些语法: 1.8.1.1 文件:main.rs fn main() …

(文章复现)低温环境下考虑电池寿命的微电网优化调度

参考文献&#xff1a; [1]丁佳昀,胡秦然,吴在军,等.低温环境下考虑电池寿命的微电网优化调度[J].中国电机工程学报,2024,44(10):3815-3824. 1.摘要 储能系统作为微电网重要组成部分&#xff0c;为微电网协调能量供需提供了解决方案。然而&#xff0c;在低温环境下&#xff0c…

《软件定义安全》之六:SDN和NFV安全实践

第6章 SDN和NFV安全实践 1.基于流的安全防护 1.1 DDoS检测清洗 DDoS检测清洗应用ADS APP的设计思路&#xff1a;借助安全控制平台中流相关的组件&#xff0c;从SDN控制器中获得相应的流量&#xff0c;并根据抗DDoS应用订阅的恶意流特征进行检测&#xff0c;发现恶意流量后&a…

最新thinkphp5内核全开源女神赢口红H5公众号版第五版(100%可经营)

最新thinkphp5内核全开源女神赢口红H5公众号版第五版&#xff08;100%可经营&#xff09; 搭建教程 1、程序为thinkPHP5开发 php版本要求5.6&#xff01;不支持虚拟主机&#xff01; 2、上传程序到您的根目录&#xff01;导入m213.sql文件&#xff01;修改数据库配置文件app…

使用docker-compose搭建达梦数据库主备集群

目录 1. Docker集群的搭建 2. 检查主备数据库 3. 主备集群的JDBC连接设置 1. Docker集群的搭建 达梦的镜像文件都是tar文件&#xff0c;通过docker load命令导入&#xff1a; docker load -i dm8_20240422_x86_rh6_64_rq_ent_8.1.3.140.tar 成功导入后&#xff0c;可看到…

Android程序设计课程教学解决方案

引言 随着信息技术的飞速发展&#xff0c;智能手机和移动应用已成为现代生活不可或缺的一部分。Android作为全球最大的移动操作系统&#xff0c;其开发人才需求量巨大。高职院校作为培养高素质技能人才的重要基地&#xff0c;如何在Android程序设计课程中有效提升学生的实践能力…

7、安装依赖、连接数据库

安装依赖、连接数据库 打开datagrip软件 连接本地数据库,第一次连接会提示安装驱动,保持网络畅通跟着点击即可 创建一个sql控制台: 创建一个数据库(数据库名称可以自取) create database fullStackBlog;右击数据库新建控制台,用于创建数据表 创建一个blog的表 …

IP协议报文格式

IP协议报文格式 一: 报头格式1.1 : 4位版本1.2 : 4位首部长度1.3 : 8位服务类型 :1.4 : 16位总长度(字节数)1.5 : 8位生存时间(TTL)1.6 : 8 位协议1.7 : 32 位源IP / 32 位目的IP 一: 报头格式 1.1 : 4位版本 现在使用的也就只有IPv4,IPv6 1.2 : 4位首部长度 以 4字节为单位…

目前比较好用的LabVIEW架构及其选择

LabVIEW提供了多种架构供开发者选择&#xff0c;以满足不同类型项目的需求。选择合适的架构不仅可以提高开发效率&#xff0c;还能确保项目的稳定性和可维护性。本文将介绍几种常用的LabVIEW架构&#xff0c;并根据不同项目需求和个人习惯提供选择建议。 常用LabVIEW架构 1. …

开源VisualFbeditor中文版,vb7 IDE,VB6升级64位跨平台开发安卓APP,Linux程序

吴涛老矣&#xff0c;社区苦无64位易语言&#xff0c;用注入DLL增强菜单&#xff0c;做成VS一样的界面 终归是治标不治本&#xff0c;一来会报毒&#xff0c;二来闭源20年没更新了 开源的VB7&#xff0c;欢迎易语言的铁粉进群&#xff1a;1032313876 【Freebasic编程语言】编绎…

服务部署:解决Docker容器与虚拟机主机之间MySql连接访问问题

一、场景&#xff1a; 虚拟机上Ubuntu系统安装了Mysql&#xff0c;现在有一个服务应用需要使用docker来部署&#xff0c;服务应用需要连接mysql做数据库基础使用&#xff0c;配置文件中配置了虚拟主机的IP和端口&#xff0c;但是还是无法连接到Mysql&#xff0c;报错无法连接超…

Characters 2 01(卡通可爱人物动画模型)

● 包裹● - 26名男子; - 29个女孩。 ● 使用地点 ● - 游戏。针对游戏引擎优化的模型; -乘法; 广告和营销; - 虚拟现实/增强现实。 ● 特点 ● - 你可以很容易地改变物体的颜色 - 使用UV贴图; - 对象逻辑位置的枢轴; - 模型具有逻辑名称。 ● 几何学● 62个独特的资产(…

【MySQL】(基础篇七) —— 通配符和正则表达式

通配符和正则表达式 本章介绍什么是通配符、如何使用通配符以及怎样使用LIKE操作符进行通配搜索&#xff0c;以便对数据进行复杂过滤&#xff1b;如何使用正则表达式来更好地控制数据过滤。 目录 通配符和正则表达式LIKE操作符百分号(%)通配符下划线(_)通配符 通配符使用技巧正…

VitePress+Docker+jenkins构建个人网站

VitePress官网 VitePress | 由 Vite 和 Vue 驱动的静态站点生成器 可以理解为一个前端脚手架:快速生成个人站点 最好先大概看一遍 快速开始 | VitePress 可以在线体验一下 安装条件 node -v 检查下node版本 在D盘创建一个文件夹 例如:VitePress 进入文件夹 cmd npm ini…

xshell远程无法链接上VM的centos7

1、现象如下&#xff0c; 2.1解决办法&#xff1a;查证后发现这个默认的设置为vmnet0 2.2解决办法&#xff1a;重启win10的虚拟机网卡&#xff08;先禁用再启用&#xff09; 3.参考文章&#xff1a;Xshell连接不上虚拟机centos7_centos7的nat模式可以ping通网络,但是用xshell连…

深入浅出LLM大语言模型

一. 前言 2022年末&#xff0c;聊天程序ChatGPT的上线&#xff0c;在短短5天被注册用户就破百万。ChatGPT的爆火&#xff0c;在一夜之间&#xff0c;带领人类穿越到了真正的人工智能时代。 本文会从ChatGPT作为切入点&#xff0c;在介绍其底层的GPT模型诞生史后&#xff0c;再…

基于SSM+Jsp的交通事故档案管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

打造精细化运维新玩法(三)

实践SLO&#xff0c;概括下就是在相对标准、统一的框架下指导和推动服务质量的数字化建设&#xff0c;形成对组织有价值的数据资产和流程规范。借用在人工智能和机器学习领域的观点&#xff0c;算法的上限受限于数据质量的好坏&#xff0c;所以从源头上建设高质量的数据非常重要…

2024年城市建设、运输与智慧交通国际会议(ICUCTST 2024)

2024 International Conference on Urban Construction, Transportation, and Smart Transportation 【1】大会信息 会议简称&#xff1a;ICUCTST 2024 大会地点&#xff1a;中国厦门 会议官网&#xff1a;www.icuctst.com 投稿邮箱&#xff1a;icuctstsub-paper.com 【2】会…

打工人和学生党的福利,NewspaceGpt使用新体验

使用地址&#xff1a;https://newspace.ai0.cn/ 个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮…