喜欢看排序算法动态效果的,可以看看这个网站

https://visualgo.net/zh/sorting

里面很多算法的动画解释,可以看到算法的排序效果,而且还附带了伪代码的实现过程。

本来想录制几张动图放上来,但是因为图片较大,传不上来,公众号对动态图片有限制,喜欢的同学可以点击我上面的链接,自己去尝试一下。

我画了一个图片,用来表示归并排序的运算过程

排序的过程

先把需要排序的数据分成两份。

把两份的数据依次进行排序并组合在一起。

再把排序后的两组数据进行并入一起排序。

好了,写代码吧

我们先实现,「把两份的数据依次进行排序并组合在一起

下面是实现这个的算法过程

/** r[] : 需要排序的数组* s[] : 排序后保存数据的数组* left: 排序的起始位置* mid : 排序的中间位置* right:排序的最右边位置*/
int merge(int r[],int s[],int left,int mid,int right)
{int i,j,k;i=left;j=mid+1;k=left;for(;i <= mid && j<=right;){if(r[i]<=r[j])s[k] = r[i++];elses[k] = r[j++];k++;}for(;i<=mid;)s[k++]=r[i++];for(;j<=right;)s[k++]=r[j++];return 0;
}

如果我们对两个数进行排序

经过上面的那个函数排序后,我们会把[3,1]排序成[1,3]。

——

那,如果我们需要对4个数字进行排序呢?

我们需要先把4个数字分成2组

然后,我们需要依次对上面的两组数据进行排序,得到下面新的两组数据

然后,我们需要把已经排序的两个数组进行排序

s[] 是保存的排序结果,r[] 是需要排序的数组。

left,mid,right 是排序数组中的三个位置。

left = 0;

right = 3;

mid = ( left + right )/2 = 1;

进入函数体,我们需要三个变量来协助我们进行运算

i = left = 0;

j = mid +1 = 1 +1 = 2;

k = left = 0;

它们看起来是这样子的

把r[i] 和 r[j] 两个数进行比较,把小的那个数放到s[k] 里面,然后再移位

比较之后变成

然后再执行下面的代码

for(;i <= mid && j<=right;){if(r[i]<=r[j])s[k] = r[i++];elses[k] = r[j++];k++;
}

这时候 j = 4

这时候就退出了 for 循环

退出for 循环后 就开始执行下面的 for 循环

 for(;i<=mid;)s[k++]=r[i++];for(;j<=right;)s[k++]=r[j++];

这样后,会变成这样

这样就退出 merge 函数

经过上面的过程,我们需要应该有点悟性,我们需要使用递归来解决这些问题

可以看下面的文章了解啥是递归

C 语言,你真的懂递归了吗?

然后呢,我们就写了一个这样的递归函数,放心吧,在学习树的时候,也是需要这种递归操作的。

/** r[] : 需要排序的数组* s[] : 排序后保存数据的数组* left: 排序的起始位置* right:排序的最右边位置*/
int merge_sort(int r[],int s[],int left,int right)
{int mid;int t[20];if(left==right)s[left]=r[right];else{mid=(left+right)/2;merge_sort(r,t,left,mid);/*sort left~mid*/merge_sort(r,t,mid+1,right);/*sort mid+1~right*/merge(t,s,left,mid,right);/*merge sort left,mid,right*/}return 0;
}

这个函数就是递归函数,递归最后退出机制是

left == right 

再然后,我们需要一个 main 函数

完整的代码实现如下

#include <stdio.h>
#include <stdlib.h>/** r[] : 需要排序的数组* s[] : 排序后保存数据的数组* left: 排序的起始位置* mid : 排序的中间位置* right:排序的最右边位置*/
int merge(int r[],int s[],int left,int mid,int right)
{int i,j,k;i=left;j=mid+1;k=left;for(;i <= mid && j<=right;){if(r[i]<=r[j])s[k] = r[i++];elses[k] = r[j++];k++;}for(;i<=mid;)s[k++]=r[i++];for(;j<=right;)s[k++]=r[j++];return 0;
}/** r[] : 需要排序的数组* s[] : 排序后保存数据的数组* left: 排序的起始位置* right:排序的最右边位置*/
int merge_sort(int r[],int s[],int left,int right)
{int mid;int t[20];if(left==right)s[left]=r[right];else{mid=(left+right)/2;merge_sort(r,t,left,mid);/*sort left~mid*/merge_sort(r,t,mid+1,right);/*sort mid+1~right*/merge(t,s,left,mid,right);/*merge sort left,mid,right*/}return 0;
}int main()
{int a[8] = {6,5,3,1,8,7,2,4};int i;merge_sort(a,a,0,7);for(i=0;i<sizeof(a)/sizeof(a[0]);i++)printf("%d ",a[i]);printf("\n");return 0;
}

程序输出

1 2 3 4 5 6 7 8

算法复杂度,翻开以前写的文章

时间复杂度和空间复杂度,一看就懂,面试前必过一遍

中间是 mid = (left+right)/2

可以猜到是 O(logN) ,也就是排序的时间是用logN时间去拆分的,而且拆分的时候,我们还需要进行排序,也就是代码里面提到的,排序的时间是O(n),所以在拆分和排序中需要花费的时间是 O(NlogN)。

拆分需要花费 O(logN) ,那合并的时候自然也需要花费O(logN)

总的算法时间是

O(NlogN + logN)  = O(NlogN)


推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

C语言,谁都能看得懂的归并排序相关推荐

  1. [免费专栏] Android安全之Android Xposed插件开发,小白都能看得懂的教程

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...

  2. 小白都能看得懂的教程 一本教你如何在前端实现markdown编辑器

    小白都能看得懂的教程 一本教你如何在前端实现markdown编辑器   大家好,我是亓官劼(qí guān jié ),在[亓官劼]公众号.CSDN.GitHub.B站.华为开发者论坛等平台分享一些技 ...

  3. yolov5使用2080ti显卡训练是一种什么样的体验我通过vscode搭建linux服务器对python-yolov5-4.0项目进行训练,零基础小白都能看得懂的教程。>>>>>>>>>第二章番外篇

    第二章番外篇:yolov5通过vscode搭建linux服务器对python-yolov5-4.0项目进行训练,零基础小白都能看得懂的教程.YOLOv5搭建的最快搭建方式,踩坑经历详谈 前期准备: 2 ...

  4. yolov5-4.0环境搭建,零基础小白都能看得懂的教程。YOLOv5搭建的最快搭建方式,踩坑经历详谈)yolov5/yolov4/yolov3/yolov3通>>>>>>>>>>>>>>>>>第一章

    第一章:python最新YOLOv5-4.0环境搭建,零基础小白都能看得懂的教程.YOLOv5搭建的最快搭建方式,踩坑经历详谈 环境准备: yolov5-4.0环境搭建整体说明 2,anaconda的 ...

  5. 为什么学习C语言这么久,看的懂代码,做不出题,写不出来项目?

    前言 我看得懂别人的程序,可是我自己却写不出来,我应该怎么办啊? 你了解这些嘛? 你只是能从别人书写的代码知道每一步都做些什么吧? 你明白别人的解题思路吗? 你知道别人为什么要用那样的算法吗? 如果你 ...

  6. 小白都能看得懂的java虚拟机内存模型

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:土豆是我的最爱 blog.csdn.net/qq_37141 ...

  7. 【深度学习】人人都能看得懂的卷积神经网络——入门篇

    近年来,卷积神经网络热度很高,在短时间内,这类网络成为了一种颠覆性技术,打破了从文本.视频到语音多个领域的大量最先进的算法,远远超出其最初在图像处理的应用范围. 卷积神经网络的一个例子 在客流预测.信 ...

  8. 你画的流程图,全组人都能看得懂吗?

    自媒体行业有一句不知道是谁说的名言:用户有图就不会看文字,有视频就不会看图.虽然这里反应出了现代人的一些浮躁,但也从侧面说明在沟通效率方面,视频优于图片,图片优于文字.而平时大家又都在抱怨老人没有留下 ...

  9. 轻松使用终端开启macOS系统的隐藏功能,小白都能看得懂

    不管是在Windows系统还是在macOS系统中,都有一个名为"终端"的应用,对于我们普通人来说它就好像是个很深奥的东西,只有技术流,程序猿才能驾驭.其实不然,今天未来小编就整理了 ...

最新文章

  1. SpringBoot请求日期参数异常(Failed-to-convert-value-of-type-'java-lang-String'-
  2. Java新手小程序之三
  3. 如何从校招脱颖而出?支付宝程序媛王妍岩:自信+方法
  4. Missing you is a kind of my deep-pain in my life
  5. 印刷体是什么意思_家长晒出4年级小学霸课前笔记,字迹堪比“印刷体”,老师都羡慕...
  6. 西门子v90伺服说明书_西门子V90伺服驱动器的的EPOS控制模式
  7. 走进我的交易室01_引子
  8. 第二次作业—熟悉使用工具
  9. 计算机全键在线使用说明书,笔记本电脑键盘介绍图,笔记本键盘全部按键功能介绍说明-系统城...
  10. HLS、Smooth Streaming、HDS和Dash
  11. vue对象属性为null_vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题...
  12. 计算机快捷键任务管理器,任务管理器快捷键,教您win10怎么打开任务管理器
  13. Unity3D Shader编程】之六 暗黑城堡篇: 表面着色器(Surface Shader)的写法(一)
  14. ACM-ICPC 2018 沈阳赛区网络预赛 J Ka Chang(树分块)
  15. 飞天技术汇 | 你用Kubernetes的样子很酷!
  16. 移动、联通、电信卡的接入点名称
  17. mysql read buffer_mysql 参数read_rnd_buffer_size的真正含义
  18. ZOL桌面壁纸的提取
  19. Laravel 自定义错误页面
  20. 【TS】546- 掌握 TS 这些工具类型,让你开发事半功倍

热门文章

  1. 圆桌论坛对话:互联网产业革命
  2. myeclipse试用小记----Hibernate多对一双向关联(2)
  3. 搞了个30天学习量化的数据资料,可以bt做全球。数据链接白送
  4. 分布式 ID的 9 种生成方式
  5. Python 第三方模块之 PDFMiner(pdf信息提取)
  6. 关于eclipse项目红色感叹号的解决办法
  7. cocoa pods的安装与我遇到的问题
  8. 【原】通过npm script运行webpack的原理
  9. UVA 213 Message Decoding
  10. pyplot交互地画多个plot