归并排序(C语言)

目录

1.归并排序图解

2.归并排序(递归版)

3.归并排序(非递归版)


1.归并排序图解

归并排序的核心思想是让左右两边有序的部分进行合并比较排序,具体什么意思呢?分两点:

1.分:左右两边要有序,如何做到左右两边有序呢?看上面的图,当我们将一个数组进行分离,一直分,知道左右两边进行对比的数只有一个,这种情况下肯定有序。

2.治:这个过程就是将左右两边数进行排序,然后排好后再进行重复操作,就将整个数组置为有序了。

我们用代码来加深整个过程的理解。

2.归并排序(递归版)

我们先来讲这个递归版本的代码思想:

我这里传的四个参数分别是:a--数组,begin--头下标,end--尾下标,tmp用来拷贝的数组。

从图中我们不难发现分的过程是一个除以2倍的关系,所以我们用mid来记录接下来递归的左边尾下标和右边头下标,递归终止条件就是头下标大于等于尾下标的时候,接下来我们进行的操作就是定义一下左边的头尾下标和右边的头尾下标,还有一个i用作tmp的下标,接下来就开始比对了,我们进行升序排序,所以我们把小的往tmp里放,循环的结束条件就是左右两边随便一边走完就停止,接下来再把没输完的全部输进去就好,不要忘记我们的tmp充当的是临时拷贝的角色,我们要改动的是数组a,所以我们使用库函数memcpy来将tmp里的数拷贝到a中,这样就模拟了治的过程,也就是说每一趟递归我们a里的值跟上面图片治部分的每一行是一样的。

我们来看看结果:

归并是一种时间复杂度为O(NlogN)的排序算法,而且它的稳定性也比较高。

我们再来感受一下不用递归,归并怎么来写。

3.归并排序(非递归版)

//归并排序 非递归实现
void MergeSortNrec(int* a, int begin, int end, int* tmp)
{int gap = 1;while (gap < end+1){for (int i = 0; i < (end - begin + 1); i += 2*gap){int begin1 = i, end1 = i + gap-1;int begin2 = i + gap, end2 = i + gap * 2-1;int j = begin1;if (end1 >= end+1|| begin2 >= end+1){break;}if (end2 >= end+1){end2 = end;}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;}
}

非递归版我们采用的逻辑还是一样的,只不过实现形式有很大区别,递归中我们是分治,用递归达到分的目的,这里我们没有递归,怎么办呢,我们可以用循环来实现,这里我就不卖关子了,我们的总体思路是直接到分的最后一步,也就是一个跟一个比的情款,然后再往回去走。

所以,上面代码中的gap的作用就是控制对比元素的个数,一开始一个跟一个对比,每一趟新的循环gap阔两倍,然后治的过程,代码跟我们递归版的是相差无几的,但是这里的end1,begin2,end2要注意有可能会发生越界的情况,所以我们要对他们进行判断,当end1和begin2中的任意一个出现越界情况的话,我们就终止循环,因为光是左边的就已经到尾了,就没必要比右边了(右边压根没数据了);如果是end2越界,说明这个数组长度不是gap的整数倍了,我们就将end2重置为尾下标就行了,保证了不会出现越界的行为。

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

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

相关文章

【数据结构】排序之归并排序与计数排序

个人主页 &#xff1a; zxctsclrjjjcph 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 目录 1. 前言2. 归并排序2.1 递归实现2.1.1 分析2.1.2 代码实现 2.2 非递归实现2.2.1 分析2.2.2 代码实现 3. 计数排序3.1 分析3.2 代码实现 4. 附代码4.1 Sort.h4.2 Sort.c4.3…

没有自动化测试项目经验,3个项目帮你走入软测职场!

学习自动化测试最难的是没有合适的项目练习。测试本身既要讲究科学&#xff0c;又有艺术成分&#xff0c;单单学几个 API 的调用很难应付工作中具体的问题。 你得知道什么场景下需要添加显性等待&#xff0c;什么时候元素定位需要写得更加优雅&#xff0c;为什么需要断言这个元…

1. 安装Git

01. 安装Git 最早Git是在Linux上开发的&#xff0c;很长一段时间内&#xff0c;Git也只能在Linux和Unix系统上跑。不过&#xff0c;慢慢地有人把它移植到了Windows上。现在&#xff0c;Git可以在Linux、Unix、Mac和Windows这几大平台上正常运行了。 要使用Git&#xff0c;第一…

centos7 arm服务器编译安装gcc 8.2

前言 当前电脑的gcc版本为4.8.5&#xff0c;但是在编译其他依赖包的时候&#xff0c;出现各种奇怪的问题&#xff0c;会莫名其妙的中断编译。本地文章讲解如何自编译安装gcc&#xff0c;替换系统自带的gcc。 环境准备 gcc 需要 8.2&#xff1a;下载地址 开始编译 1、解压gcc…

智能反射面—流形优化

使用Manopt工具箱适合优化最小化问题&#xff0c;如果你的优化问题是最大化问题&#xff0c;那么需要将其转换为最小化问题然后使用Manopt工具箱求解。 具体安装过程 Matlab添加Manopt - 知乎 (zhihu.com) 优化问题 clc,clear; close all; srng(1);%rand seed N10; GR_num1e3…

[论文阅读]DeepFusion

DeepFusion Lidar-Camera Deep Fusion for Multi-Modal 3D Object Detection 用于多模态 3D 物体检测的激光雷达相机深度融合 论文网址&#xff1a;DeepFusion 论文代码&#xff1a;DeepFusion 摘要 激光雷达和摄像头是关键传感器&#xff0c;可为自动驾驶中的 3D 检测提供补…

详解IP安全:IPSec协议簇 | AH协议 | ESP协议 | IKE协议_ipsec esp

目录 IP安全概述 IPSec协议簇 IPSec的实现方式 AH&#xff08;Authentication Header&#xff0c;认证头&#xff09; ESP&#xff08;Encapsulating Security Payload&#xff0c;封装安全载荷&#xff09; IKE&#xff08;Internet Key Exchange&#xff0c;因特网密钥…

进程间通信之匿名管道通信

每一次的努力都是自我成长的一步&#xff0c;坚持不懈的付出会铺就通向成功的道路。文章目录 进程间通信的介绍进程间通信的发展进程间通信的分类进程间通讯的本质资源&#xff1f;这个资源谁提供的&#xff1f; 管道什么是管道匿名管道管道小总结现在我给大家看一下管道通信的…

【openwrt】【overlayfs】Openwrt系统overlayfs挂载流程

overlayfs是一种叠加文件系统&#xff0c;在openwrt和安卓系统中都有很广泛的应用&#xff0c;overlayfs通常用于将只读根文件系统(rootfs)和可写文件系统(jffs2)进行叠加后形成一个新的文件系统&#xff0c;这个新的文件系统“看起来”是可读写的&#xff0c;这种做法的好处是…

010:vue结合el-table实现表格小计总计需求(summary-method)

文章目录 1. 实现效果2. 核心部分3. 完整组件代码4. 注意点 1. 实现效果 2. 核心部分 el-table 添加如下配置&#xff0c;添加 show-summary 属性&#xff0c;配置 summary-method 函数 <el-table.......show-summary:summary-method"getSummaries" >...... …

QuestDB时序数据库快速入门

简介 QuestDB是一个开源的高性能时序数据库&#xff0c;专门用于处理时间序列相关的数据存储与查询&#xff1b; QuestDB使用列式存储模型。数据存储在表中&#xff0c;每列存储在其自己的文件和其自己的本机格式中。新数据被附加到每列的底部&#xff0c;以便能够按照与摄取…

智能光栅光片显微成像技术的LabVIEW解决方案

智能光栅光片显微成像技术的LabVIEW解决方案 在生物医学研究中&#xff0c;高效的成像技术对于捕捉细胞内罕见和复杂事件至关重要。智能光栅光片显微技术&#xff08;smartLLSM&#xff09;的出现&#xff0c;代表了LabVIEW软件在高端成像领域的革命性应用&#xff0c;这项技术…