【C语言】【排序算法】----- 归并排序

由于最近要考试,好久没有发博客了,非常抱歉大家对我的支持。之后我会不断更新博客,继续创作出高质量的文章,希望能帮到大家!

文章目录

  • 一、归并排序基本思想
  • 二、递归实现
  • 三、非递归实现
  • 四、效率分析

一、归并排序基本思想

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法,即分解和合并。先使每个子序列有序,再使子序列段间有序,最后合并成一个有序数组。
在这里插入图片描述

二、递归实现

  1. 基本思路:
    ① 申请一个空间tmp,大小为两个已经排好序列之和,该空间用来存放合并后的序列。
    ② 设定两个下标,分别指向两段已排好序的起始位置。
    ③ 比较两个下标所指向的元素大小,选择较小的元素放入到合并空间,并且移动指针指向下一位置。
    ④ 不断重复步骤③,直到当某一指针到达序列尾部。
    ⑤ 然后将另一序列剩下的所有元素直接插入到合并序列的尾端。
  2. 代码实现:
//归并排序递归
void _MergeSort(int* a, int* tmp, int begin, int end)
{//只有一个元素或不存在这样的区间时if (begin >= end){return;}//分成两段区间,分别有序时在进行归并int mid = (begin + end) / 2;_MergeSort(a, tmp, begin, mid);_MergeSort(a, tmp, mid + 1, end);//第一个数组的两端int begin1 = begin, end1 = mid;//第二个数组的两端int begin2 = mid + 1, end2 = end;//由于两段数组都是从begin开始,因此将begin给i确保其在相同的区间上int i = begin;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[i++] = a[begin1++];}else{tmp[i++] = a[begin2++];}}//有一个排完了,剩下的直接放入while (begin1 <= end1){tmp[i++] = a[begin1++];}while (begin2 <= end2){tmp[i++] = a[begin2++];}//tmp已经归并成功,将tmp复制会数组a中memcpy(a + begin, tmp + begin, (end - begin + 1) * sizeof(int));
}void MergeSort(int* a, int n)
{assert(a);//创建一个临时数组int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}_MergeSort(a, tmp, 0, n - 1);free(tmp);tmp = NULL;
}

三、非递归实现

非递归实现是一种迭代式的排序算法,它避免了递归所带来的额外开销,通常使用循环的方式来解决。

  1. 基本思路:
    将一个数组通过gap分为几组进行合并,然后让gap每次扩大2倍,但gap < 数组元素个数的大小。
  2. 越界问题:
    我们可以很容易想到代码实现的思路,但难点就在于如何控制每一段区间的边界,从而避免下标越界的问题。
    这里有三种可能会出现越界的问题,分别为:
    ①当第一段区间末尾end1大于或等于该区间元素个数。
    ②当第二段区间不存在,需要进行修改区间。
    解决方法:
    ①第一种问题我们可以让其直接break。因为其右边没数据存在,因此就算进入循环中剩余的元素也不会发生改变。
    ②第二种问题,当第二段区间bgein2大于或等于该区间元素个数时,不进入循环,直接break;当第二段区间的结尾end2大于或等于n时,我们只需将end2修改为n-1即可,因为n-1正好为整个数组的边界。
  3. 代码实现:
    注意:
    当我们将临时数组tmp拷贝回原数组时:
    ①起始点为:tmp + i,因为i是每次归并后第一个元素的第一个位置。
    ②拷贝回去的元素个数:end2 - i + 1。因为end2指向的每次归并后第二组元素的最后一个位置,而i所指向的是每次归并后的第一个元素的第一个位置。
//归并排序的非递归实现
void MergeSortNonR(int* a, int n)
{	//开辟一个临时数组,来存取排好序的元素int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}int gap = 1;int i = 0;int j = 0;while (gap < n){for (i = 0; i < n; i += 2 * gap){//[i,i+gap-1]  [i+gap,i+2*gap-1}int begin1 = i;int end1 = i + gap - 1;int begin2 = i + gap;int end2 = i + 2 * gap - 1;j = i;// 考虑end1 begin2 end2三者分别越界的问题if (end1 >= n){break;}else if (begin2 >= n){break;}else if (end2 >= n){end2 = n - 1;}while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[j++] = a[begin1++];}else{tmp[j++] = a[begin2++];}}while (begin1 <= end1){tmp[j++] = a[begin1++];}while (begin2 <= end2){tmp[j++] = a[begin2++];}memcpy(a + i, tmp + i, sizeof(int) * (end2 - i + 1));}gap *= 2;}free(tmp);tmp = NULL;
}

四、效率分析

归并排序的时间复杂度为:O(N * log2N) 因为向下递归的时间复杂度为O(log2N),再遍历一次数组的时间复杂度为O(N)。

归并排序的空间复杂度为:O(N) 需要创建一个辅助数组tmp用来存归并后的序列。

归并排序的稳定性:稳定。根据arr[begin1] <= arr[begin2],我们可以得出相同的元素先排第一组,然后再排第二组的元素,因此相同元素的相对位置不会改变。

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

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

相关文章

LlamaFactory可视化微调大模型 - 参数详解

LlamaFactory 前言 LLaMA Factory 是一个用于微调大型语言模型的强大工具,特别是针对 LLaMA 系列模型。 可以适应不同的模型架构和大小。 支持多种微调技术,如全参数微调、LoRA( Low-Rank Adaptation )、QLoRA( Quantized LoRA )等。 还给我们提供了简单实用的命令行…

汉初三杰韩信,是不是颍川人

再重复一次&#xff0c;此韩信非彼韩信&#xff0c;说的是汉初三杰淮阴侯韩信&#xff0c;不是韩王信。 他俩的共同之处还真多&#xff0c;同名同姓&#xff0c;都被封王&#xff0c;八大异姓王韩姓占了两位。而且&#xff0c;结局也一样&#xff0c;都因反判罪被朝廷处死。这…

springboot篮球馆管理系统-计算机毕业设计源码21945

目 录 摘要 1 绪论 1.1选题背景 1.2研究意义 1.3论文结构与章节安排 2 篮球馆管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分析 2.4 …

NodeJS小饰品销售管理系统-计算机毕业设计源码21597

摘 要 在当今的数字化时代&#xff0c;电子商务已经成为了商业领域中不可或缺的一部分。随着消费者对于购物体验的要求越来越高&#xff0c;一个高效、便捷、用户友好的小饰品销售管理系统显得尤为重要。 本系统旨在利用 JavaScript 技术&#xff0c;设计并实现一个功能强大的小…

越南语是一门什么样的语言?如何学好越南语?

越南语是一种南亚语系越芒语族的语言&#xff0c;具有丰富的汉语借词&#xff0c;尤其在抽象概念的表达上&#xff0c;汉越词汇占有很大比例。作为一种声调语言&#xff0c;越南语拥有六个声调&#xff0c;这使得其发音具有音乐性和节奏感。它是一种孤立语&#xff0c;依赖于语…

强化学习实战2:动手写迷宫环境

迷宫环境介绍与创建 迷宫环境图示如下&#xff1a; 如图所示&#xff0c;其为一个 三乘三 的网格世界&#xff0c;我们要让 agent 从 S0 采取策略出发&#xff0c;然后走到 S8&#xff0c;图中红线部分表示障碍不能逾越&#xff0c;其中 S1 和 S4 之间有一个障碍&#xff0c;S…

换新启航环游浪漫新篇章

✨&#x1f389;【焕新启航&#xff0c;环游浪漫新篇章 —— 《焕新环游传》盛大开播】&#x1f389;✨在时光的温柔转角&#xff0c;一场前所未有的梦幻之旅悄然拉开序幕&#xff01;&#x1f31f;《焕新环游传》—— 这不仅仅是一部剧集的开播&#xff0c;更是对过往角色遗憾…

Springboot 设置个性化banner

在 Spring Boot 中自定义 banner 的方法有几种&#xff0c;可以通过以下步骤来实现&#xff1a; 1、使用文本文件作为 banner 在 src/main/resources 目录下创建一个名为 banner.txt 的文件。 编辑这个文件&#xff0c;输入想要显示的文本。确保文本中包含换行符和空格…

Vue 项目中 history 路由模式的使用

在最近帮客户开发的一个项目中&#xff0c;由于项目的特殊性&#xff0c;需要用到 Vue 中的 history路由模式。该模式使用时会涉及到“上传白屏”和“刷新 404 问题”。在帮助客户解决这两个问题的过程中&#xff0c;总结问题的解决方案并记录下来&#xff0c;希望能够保留这篇…

将格内多行文字展开成多格

表格的A列是分类&#xff0c;B列由多行文字组成&#xff0c;即分隔符是换行符。 AB1Account NumberInteraction21Jan 1,2023 - Hello.32Jan 2, 2023 - Good morning. Jan 3, 2023 - Good night. Jan 4, 20 Jan 5, 2023 - Good night. Jan 6, 2023 - Good afternoon.43Jan 1,20…

中霖教育:经济师的十个专业类别怎么选?

经济师一共包含十个专业类别&#xff0c;分别是工商管理、农业经济、财政税收、金融、保险、人力资源管理、旅游经济、运输经济、建筑与房地产经济、知识产权。 经济师选择报考专业时有哪些建议? 1、职业规划是选择专业的首要考虑点。未来的职业发展途径应与所选专业紧密相连…

wifi模组Ai-M62-32S的IO映射和UDP透传测试

wifi模组Ai-M62-32S的IO映射和UDP透传测试 基本IO 映射配网示例开启UDP透传示例复位AT查询wifi是否在线配置DHCP静态IP连接wifi连接UDP开启透传 基本IO 映射 对于wifi模组Ai-62-32S来说其模组 IO 引脚&#xff08;从模组左上角逆时针排序&#xff0c;引脚序号从 1 开始&#x…

python+selenium-UI自动框架之[优化]元素查找和BasePage页面

痛点&#xff1a;在页面查找元素的时候会遇到找不到或者其他无法处理某个字段的情况&#xff0c;又或者想要在输出的log或者report里面显示这个字段名称&#xff0c;这时候加上字段名称就很重要&#xff01; [3]pythonselenium - UI自动框架之封装查找元素https://mp.csdn.net…

前端如何去看蓝湖

首先加入团队&#xff0c;在内容中我们可以看到点击图片&#xff0c;右边出现的图 包含了像素甚至有代码&#xff0c;我们可以参考这个代码。 那么在使用之前我们需要调整好像素&#xff0c;例如我们的像素宽为375&#xff0c;不用去管高&#xff0c;然后这个宽度我们可以去自…

camera-qsc-crosstalk校准数据XTALK回写

问题背景 手机越做越紧凑&#xff0c;需要模组和芯片尺寸越做越小&#xff0c;在尺寸一定的基础上&#xff0c;高像素和大像素&#xff0c;对于手机摄像头来说&#xff0c;一直是一对矛盾的存在。 高像素&#xff1a;带来高分辨率画质大像素&#xff1a;带来暗态下高感光度和…

linux radix-tree 基数树实现详解

radix tree&#xff0c;又称做基数树&#xff0c;是一种适合于构建key(index)与value(item)相关联的数据结构。内核中使用非常广泛。本文主要聚焦linux内核基数树的代码实现,大量注释过的代码。 radix-tree组织结构如下: 1、数据结构 /** The bottom two bits of the slot de…

首届UTON区块链开发者计划大会在马来西亚圆满落幕

7月9日&#xff0c;首届UTON区块链开发者计划大会在马来西亚吉隆坡成功举办&#xff01; 来自全球顶尖的行业领袖、技术精英和众多区块链爱好者参与了此次盛会&#xff0c;也标志着UTON区块链生态进入了一个全新的发展阶段。 会上&#xff0c;UTON区块链创始人之一唐毅先生以“…

Linux运维:MySQL中间件代理服务器,mycat读写分离应用实验

Mycat适用的场景很丰富&#xff0c;以下是几个典型的应用场景&#xff1a; 1.单纯的读写分离&#xff0c;此时配置最为简单&#xff0c;支持读写分离&#xff0c;主从切换 2.分表分库&#xff0c;对于超过1000万的表进行分片&#xff0c;最大支持1000亿的单表分片 3.多租户应…

(pyqt5)弹窗-Token验证

前言 为了保护自己的工作成果,控制在合理的范围内使用,设计一个用于Token验证的弹窗. 代码 class TokenDialog(QDialog):def __init__(self, parentNone, login_userNone, mac_addrNone, funcNone):super(TokenDialog, self).__init__(parent)self.login_user login_userself…

为什么说java只要还是泛型擦除,就不要吹自己高性能?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“666”之后私信回复“666”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;关于“Java只要还是泛型擦除…