C语言,谁都能看得懂的归并排序
喜欢看排序算法动态效果的,可以看看这个网站
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语言,谁都能看得懂的归并排序相关推荐
- [免费专栏] Android安全之Android Xposed插件开发,小白都能看得懂的教程
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...
- 小白都能看得懂的教程 一本教你如何在前端实现markdown编辑器
小白都能看得懂的教程 一本教你如何在前端实现markdown编辑器 大家好,我是亓官劼(qí guān jié ),在[亓官劼]公众号.CSDN.GitHub.B站.华为开发者论坛等平台分享一些技 ...
- yolov5使用2080ti显卡训练是一种什么样的体验我通过vscode搭建linux服务器对python-yolov5-4.0项目进行训练,零基础小白都能看得懂的教程。>>>>>>>>>第二章番外篇
第二章番外篇:yolov5通过vscode搭建linux服务器对python-yolov5-4.0项目进行训练,零基础小白都能看得懂的教程.YOLOv5搭建的最快搭建方式,踩坑经历详谈 前期准备: 2 ...
- yolov5-4.0环境搭建,零基础小白都能看得懂的教程。YOLOv5搭建的最快搭建方式,踩坑经历详谈)yolov5/yolov4/yolov3/yolov3通>>>>>>>>>>>>>>>>>第一章
第一章:python最新YOLOv5-4.0环境搭建,零基础小白都能看得懂的教程.YOLOv5搭建的最快搭建方式,踩坑经历详谈 环境准备: yolov5-4.0环境搭建整体说明 2,anaconda的 ...
- 为什么学习C语言这么久,看的懂代码,做不出题,写不出来项目?
前言 我看得懂别人的程序,可是我自己却写不出来,我应该怎么办啊? 你了解这些嘛? 你只是能从别人书写的代码知道每一步都做些什么吧? 你明白别人的解题思路吗? 你知道别人为什么要用那样的算法吗? 如果你 ...
- 小白都能看得懂的java虚拟机内存模型
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:土豆是我的最爱 blog.csdn.net/qq_37141 ...
- 【深度学习】人人都能看得懂的卷积神经网络——入门篇
近年来,卷积神经网络热度很高,在短时间内,这类网络成为了一种颠覆性技术,打破了从文本.视频到语音多个领域的大量最先进的算法,远远超出其最初在图像处理的应用范围. 卷积神经网络的一个例子 在客流预测.信 ...
- 你画的流程图,全组人都能看得懂吗?
自媒体行业有一句不知道是谁说的名言:用户有图就不会看文字,有视频就不会看图.虽然这里反应出了现代人的一些浮躁,但也从侧面说明在沟通效率方面,视频优于图片,图片优于文字.而平时大家又都在抱怨老人没有留下 ...
- 轻松使用终端开启macOS系统的隐藏功能,小白都能看得懂
不管是在Windows系统还是在macOS系统中,都有一个名为"终端"的应用,对于我们普通人来说它就好像是个很深奥的东西,只有技术流,程序猿才能驾驭.其实不然,今天未来小编就整理了 ...
最新文章
- SpringBoot请求日期参数异常(Failed-to-convert-value-of-type-'java-lang-String'-
- Java新手小程序之三
- 如何从校招脱颖而出?支付宝程序媛王妍岩:自信+方法
- Missing you is a kind of my deep-pain in my life
- 印刷体是什么意思_家长晒出4年级小学霸课前笔记,字迹堪比“印刷体”,老师都羡慕...
- 西门子v90伺服说明书_西门子V90伺服驱动器的的EPOS控制模式
- 走进我的交易室01_引子
- 第二次作业—熟悉使用工具
- 计算机全键在线使用说明书,笔记本电脑键盘介绍图,笔记本键盘全部按键功能介绍说明-系统城...
- HLS、Smooth Streaming、HDS和Dash
- vue对象属性为null_vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题...
- 计算机快捷键任务管理器,任务管理器快捷键,教您win10怎么打开任务管理器
- Unity3D Shader编程】之六 暗黑城堡篇: 表面着色器(Surface Shader)的写法(一)
- ACM-ICPC 2018 沈阳赛区网络预赛 J Ka Chang(树分块)
- 飞天技术汇 | 你用Kubernetes的样子很酷!
- 移动、联通、电信卡的接入点名称
- mysql read buffer_mysql 参数read_rnd_buffer_size的真正含义
- ZOL桌面壁纸的提取
- Laravel 自定义错误页面
- 【TS】546- 掌握 TS 这些工具类型,让你开发事半功倍