数据结构与算法基础-学习-33-归并排序

目录

一、基本思想

二、算法思路

1、合并两个有序序列

2、分治法

三、算法源码

1、MergeSortTwoSortData

2、TwoWayMergeSortRecurtionSentryQueue

四、算法效率分析

五、Linux环境编译测试

六、小感慨


排序的其他相关知识点和源码分享可以参考之前的博客:   

《数据结构与算法基础-学习-30-插入排序之直接插入排序、二分插入排序、希尔排序》,

《数据结构与算法基础-学习-31-交换排序之冒泡排序、快速排序》,

《数据结构与算法基础-学习-32-选择排序之简单选择排序、堆排序》

一、基本思想

将两个或两个以上的有序子序列“归并”为一个有序序列。

在内部排序中,通常采用的是2路归并排序。

也就是将两个位置相邻的有序子序列R[l..m]和R[m+1..n]归并为一个有序序列R[l..n]。

二、算法思路

归并排序分两个部分进行实现,第一个部分就是将两个有序的序列合并成一个有序的序列。第二部分利用递归的思想将序列拆分成多个元素进行排序。

1、合并两个有序序列

(1)两个有序序列我们放在了一个数组中进行合并。Low和Mid分别表示Pre的起始和结束节点。Mid+1和High分别表示Tail的起始和结束节点。我们这里还是以升序为例,Pre的6和Tail的4进行比较4小,4插入到新的数组中。

(2)Tail前进一,Pre的6和Tail的5进行比较5小,5插入到新的数组中。

(3)Tail前进一,Pre的6和Tail的8进行比较6小,6插入到新的数组中。

(4)Pre前进一,Pre的9和Tail的8进行比较8小,8插入到新的数组中。

(5)Tail前进一,Tail已经超过High了,说明后半段有序序列已经访问完毕,这时只需把前半段的Pre开始遍历插入到新数组即可。

2、分治法

分治法其实就是把一个任务拆成多个小的任务,小的任务都完成了就把整个大任务完成了,是一种思想,上面是给的一个序列前后正好包含两组有序的数组,如果换成是无序数组呢,我们只需要把无需数组分成两半,左边使其有序,右边使其有序,在进行合并即可,左边可以再分为两块,有一种套娃的感觉,这个时候我们是不是会联想到递归,其实递归的练习做多了,就会有这种想法冒出来,希望对大家有帮助。

三、算法源码

1、MergeSortTwoSortData

//将队列中两个有序的序列进行合并。
//例如Low到Mid升序排列,Mid加一到High升序排列。合并为一个升序队列。
Status MergeSortTwoSortData(SqQueue* Queue,QueueLenType Low,QueueLenType Mid,QueueLenType High)
{JudgeAllNullPointer(Queue);if (Queue->Flag != INT_TYPE_FLAG){return FailFlag;}QueueLenType Pre       = Low;QueueLenType Tail      = Mid + 1;int*         Array     = (int*)(Queue->Data);SqQueue*     TmpQueue  = NULL;QueueLenType i;InitSqQueue(&TmpQueue, High - Low + 1, INT_TYPE_FLAG);while (Pre <= Mid && Tail <= High){if (Array[Pre] > Array[Tail]){EnterSqQueue(TmpQueue,&(Array[Tail]));Tail++;}else if (Array[Pre] < Array[Tail]){EnterSqQueue(TmpQueue,&(Array[Pre]));Pre++;}else//等于{EnterSqQueue(TmpQueue,&(Array[Tail]));EnterSqQueue(TmpQueue,&(Array[Pre]));Tail++;Pre++;}}while (Pre <= Mid){EnterSqQueue(TmpQueue,&(Array[Pre]));Pre++; }while (Tail <= High){EnterSqQueue(TmpQueue,&(Array[Tail]));Tail++; }for (i = Low; i <= High; i++){LeaveSqQueue(TmpQueue,&(Array[0]));Array[i] = Array[0];}DestroySqQueue(&TmpQueue); LogFormat(Debug,"Merge Sort Two Sort Data OK.\n");return SuccessFlag;
}

2、TwoWayMergeSortRecurtionSentryQueue

void TwoWayMergeSortRecurtionSentryQueue(SqQueue* Queue,QueueLenType Low,QueueLenType High)
{JudgeAllNullPointer(Queue);if (Low == High){return;}else{QueueLenType Mid = (Low + High) / 2;TwoWayMergeSortRecurtionSentryQueue(Queue,Low,Mid);TwoWayMergeSortRecurtionSentryQueue(Queue,Mid + 1,High);MergeSortTwoSortData(Queue,Low,Mid,High);}
}

四、算法效率分析

情况时间复杂度是否稳定
最好O(n * log2^n)稳定
最坏O(n * log2^n)
平均O(n * log2^n)

五、Linux环境编译测试

[gbase@czg2 Sort]$ make
gcc -Wall -Wextra -O3 InsertSort.c SwapSort.c SelectSort.c MergeSort.c BucketSort.c main.c -o TestSort -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/Log/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/HashTable/include/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqQueue/ -I /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/SqStack/ -L /opt/Developer/ComputerLanguageStudy/C/DataStructureTestSrc/PublicFunction/Make/Libs/ -lPublicFunction -lLog -lSqQueue
[gbase@czg2 Sort]$ ./TestSort 
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Info  ]--SqQueue Data   :
Data           : [ 0 ,5 ,6 ,7 ,8 ,9 ,0 ,1 ,2 ,3 ,4 ]
FrontIndex     : 0
RearIndex      : 0
SqQueueLen     : 11
SqQueueMaxLen  : 11
Flag           : INT_TYPE_FLAG
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Destroy SqQueue OK
2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Destroy SqQueue OK
2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Destroy SqQueue OK
2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Destroy SqQueue OK
2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Destroy SqQueue OK
2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Destroy SqQueue OK
2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Destroy SqQueue OK
2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Destroy SqQueue OK
2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
2023-9-11--[ Debug ]--Init SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Enter SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Leave SqQueue OK
2023-9-11--[ Debug ]--Destroy SqQueue OK
2023-9-11--[ Debug ]--Merge Sort Two Sort Data OK.
2023-9-11--[ Debug ]--Two Way Merge Sort Sentry Queue OK.
2023-9-11--[ Info  ]--Sort Function Elapsed Time   : 0 s
2023-9-11--[ Info  ]--SqQueue Data   :
Data           : [ 9 ,0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ]
FrontIndex     : 0
RearIndex      : 0
SqQueueLen     : 11
SqQueueMaxLen  : 11
Flag           : INT_TYPE_FLAG
2023-9-11--[ Debug ]--Destroy SqQueue OK

六、小感慨

《C语言学习-20-归并排序》这篇是一年前写的,虽然实现方法上差不多,但是看到现在和之前的变化,感觉自己又进步了一小点,开心,大家一起加油。

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

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

相关文章

Docker入门,Docker是什么?有什么用?该怎么用?

目录 1. 项目部署时的复杂性&#xff1f; 2. Docker是如何解决依赖兼容问题的&#xff1f; 3. 众多Linux操作系统发行版的区别 4. Docker 是如何实现跨系统运行的&#xff1f; 5. Docker与虚拟机的差别 6. 镜像(Image)与容器(Container) 7. DockerHub 8. Docker 架构 …

安防监控/视频汇聚/云存储/AI智能视频分析平台EasyCVR显示CPU过载,该如何解决?

视频云存储/安防监控/视频汇聚平台EasyCVR基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。安防视频监控系统EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、云…

Java知识总结(持续更新)

一、JDK、JRE、JVM三者之间的关系&#xff1f; 1. **JDK (Java Development Kit)**&#xff1a; JDK 是 Java 开发工具包&#xff0c;它包含了用于开发 Java 应用程序的所有必要工具和库。这包括 Java 编译器&#xff08;javac&#xff09;、Java 核心类库、开发工具&#x…

《React vs. Vue vs. Angular:2023年的全面比较》

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

【LeetCode-简单题】844. 比较含退格的字符串

文章目录 题目方法一&#xff1a;单指针方法二&#xff1a;双指针方法三&#xff1a;栈 题目 方法一&#xff1a;单指针 首先每次进入循环处理之前需要对第一个字符进行判断&#xff0c;若是退格符&#xff0c;直接删掉&#xff0c;结束此次循环fast从0开始&#xff0c;如果fa…

每日一练 | 网络工程师软考真题Day32

阅读以下说明&#xff0c;答复以下【问题1】至【问题5】 【说明】 某公司内部效劳器S1部署了重要的应用&#xff0c;该应用只允许特权终端PC1访问&#xff0c;如图4-1所示。为保证通信平安&#xff0c;需要在S1上配置相应的IPSec策略。综合考虑后&#xff0c;确定该IPSec策略如…

pdf.js 微信公众号不显示问题

问题1&#xff1a; 在浏览器中能够正常显示&#xff0c; 但是在微信浏览器中不行&#xff01;解决&#xff1a; 这个是pdf.js 版本问题&#xff0c; 用2.4版本&#xff0c;微信打开就没问题了 问题2&#xff1a; 如何关闭侧边栏&#xff1f; 修改这个地方&#xff0c; 将 -1 改…

QLineEdit 类(行编辑器)

1、 QLineEdit 类是 QWidget 类的直接子类&#xff0c;该类实现了一个单行的输入部件&#xff0c;即行编辑器&#xff1b; 2、验证器(QValidator 类)和输入掩码简介&#xff1a;主要作用是验证用户输入的字符是否符合验证器 的要求&#xff0c;即限制对用户的输入&#xff0c;比…

发UPS国际快递到墨西哥的收费标准

UPS国际快递是目前全球范围内最为知名和可靠的快递服务提供商之一&#xff0c;无论是个人还是企业都可以通过UPS将包裹快速送达世界各地&#xff0c;其中包括墨西哥。所以&#xff0c;对于许多人来说&#xff0c;了解到发UPS国际快递到墨西哥的收费标准是十分重要的。 发UPS国际…

Linux常见进程类别

目录 常见进程类别 守护进程&精灵进程 任务管理 进程组 作业 作业 | 进程组 会话 w命令 守护进程 守护进程的创建 setsid()函数 daemon()函数 模拟实现daemon函数 前台进程 | 后台进程 僵尸进程 | 孤儿进程 僵尸进程的一些细节 守护进程 | 后台进程 守护…

C++-map和set

本期我们来学习map和set 目录 关联式容器 键值对 pair 树形结构的关联式容器 set multiset map multimap 关联式容器 我们已经接触过 STL 中的部分容器&#xff0c;比如&#xff1a; vector 、 list 、 deque 、forward_list(C11)等&#xff0c;这些容器统称为序列式…

关于软件的功能复用

有一些人总在说软件要复用&#xff0c;开发一个项目时要想想怎么在另一个项目中能重用。你问他怎么做到复用&#xff0c;就会听到微服务、中台一些名词 复用的层次 说到复用&#xff0c;首先要想明白复用的是啥 级别越低&#xff0c;粒度越小&#xff0c;复用的范围越广&#…

Yolov5改进算法之添加Res2Net模块

目录 1. Res2Net介绍 1.1 Res2Net的背景和动机 1.2 Res2Net的基本概念 2. YOLOV5添加Res2Net模块 Res2Net&#xff08;Residual Resolution Network&#xff09;是一种用于图像处理和计算机视觉任务的深度卷积神经网络架构。它旨在解决传统的ResNet&#xff08;Residual Ne…

【java】【SSM框架系列】【三】Maven进阶

目录 一、分模块开发与设计 1.1 分模块开发的意义 1.2 分模块开发&#xff08;模块拆分&#xff09; 二、依赖管理 2.1 依赖传递 2.2 可选依赖 2.3 排除依赖 三、聚合与继承 3.1 聚合 3.2 继承 3.3 聚合与继承的区别 四、属性管理 4.1 属性 4.1.1 属性配置与使用 …

2023 年高教社杯全国大学生数学建模竞赛题目 B 题 多波束测线问题

B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术。声波在均匀介质中作匀速直线传播&#xff0c;在不同界面上产生反射&#xff0c;利用这一原理&#xff0c;从测量船换能器垂直向海底发射声波信号&#xff0c;并记录从声波发射到信号接收的传播…

智慧工地:让工地可视化、数字化、智能化

智慧工地平台功能包括&#xff1a;劳务管理、施工安全管理、视频监控管理、机械安全管理、危大工程监管、现场物料监管、绿色文明施工、安全隐患排查、施工综合管理、施工质量管理、设备管理、系统管理等模块。 一、项目开发环境 技术架构&#xff1a;微服务 开发语言&#…

数据结构--- 树

(一)知识补充 定义 树是一种数据结构,它是由n(n≥0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。​ 它具有以下的特点: 每个节点有零个或多个子节点; 没有父节点的节点称为根节点;每一个非根…

算法训练营day44|动态规划 part06:完全背包 (完全背包、 LeetCode518. 零钱兑换 II、377. 组合总和 Ⅳ )

文章目录 完全背包518. 零钱兑换 II (求组合方法数)思路分析代码实现思考总结 377. 组合总和 Ⅳ (求排列方法数)思路分析代码实现思考总结 完全背包 完全背包和01背包问题唯一不同的地方就是&#xff0c;每种物品有无限件。 依然举这个例子&#xff1a; 背包最大重量为4。 物…

【LInux编译器gcc/g++】gcc使用方法和动静态库相关概念

目录 一.前言 二.源代码的翻译环境 三.gcc相关指令 四.动静态库 1.什么是库&#xff1f; 2.库的命名 3.库的链接方式 4.动静态链接的优缺点 5.小结 一.前言 在Windows系统上我们常用VisualStudio来进行C/C开发&#xff0c;VS并不是一款单一的软件&#xff0c;而是集成…

【刷题篇】贪心算法(一)

文章目录 分割平衡字符串买卖股票的最佳时机Ⅱ跳跃游戏钱币找零 分割平衡字符串 class Solution { public:int balancedStringSplit(string s) {int lens.size();int cnt0;int balance0;for(int i0;i<len;i){if(s[i]R){balance--;}else{balance;}if(balance0){cnt;}}return …