当前位置:网站首页>C语言实现八种排序 - 归并排序
C语言实现八种排序 - 归并排序
2022-06-11 21:36:00 【爱学代码的学生】
什么是归并排序?
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
步骤如图:

那我们要如何实现呢?
1. 递归法
代码如下:
// 归并排序
//合并两个有序数组
void Sort(int*a,int left,int mid,int right){
int*p=(int*)malloc(sizeof(int)*(right-left+1)); //开辟一个大小是right-left+1的空间
int p1=left;
int p2=mid+1;
int p3=0;
while(p1<=mid&&p2<=right){
if(a[p1]<a[p2]){
p[p3++]=a[p1++];
}
else{
p[p3++]=a[p2++];
}
}
while(p1<=mid)
p[p3++]=a[p1++];
while(p2<=right)
p[p3++]=a[p2++];
for(int j=0;j<p3;j++){
a[left+j]=p[j];
}
free(p);
}
void MergeSort(int*a,int left,int right){
int mid;
if(left>=right){ //当数组只有一个元素,可以看做有序的
return;
}
mid=(left+right)/2;
MergeSort(a,left,mid); //排序左半数组
MergeSort(a,mid+1,right); //排序右半数组
Sort(a,left,mid,right); //合并两个有序数组
} 这样我们就完成了归并排序的递归版本
2. 非递归版
从图中我们可以看出,最终先合并的是元素个数只剩一个的数组两两合并,那我们使用非递归就可以先实现最后这一步:
//非递归写法
void MergeSort2(int*a,int n){
int*tmp = (int*)malloc(sizeof(int)*n);
int gap=1;//类似于直接先进行递归方式的最后步骤
while(gap<n){
for(int i = 0 ; i < n; i += 2*gap){
int start1=i,end1=i+gap-1; //第一个区间
int start2=gap+i,end2=2*gap+i-1; //第二个区间
int index=i;//每次初始化位置都是第一个区间的起始位置
while(start1<=end1&&start2<=end2){
if(a[start1]<a[start2])
tmp[index++]=a[start1++];
else
tmp[index++]=a[start2++];
}
while(start1<=end1)
tmp[index++]=a[start1++];
while(start2<=end2)
tmp[index++]=a[start2++];
}
memcpy(a,tmp,n*sizeof(int));
gap *= 2;
}
free(tmp);
} 我们将开始数组的大小由1个开始,两两进行归并,最终完成递归的操作,那这样就结束了吗?
我们来看一下每一次归并的数组:

我们这里传入的只是9个元素大小的数组,你怎么给我越界这么多次.

那我们应该怎么去修改它,使它无法越界呢?
这里我们需要重新调整我们的区间:
int start1=i,end1=i+gap-1; //第一个区间
int start2=gap+i,end2=2*gap+i-1; //第二个区间
这是我们之前定义的区间,由上图我们也可以看到除了start1是个好孩子没有越过界,其他都犯了越界,那我们就应该对它们进行批评改正。
这里我们需要考虑三种情况:
1. 如果end1越界
2. 如果end2越界
3. 如果start2越界
修改操作如下:
if(end1>=n){
end1=n-1;
}
if(start2>=n){
start2=n;
end2=n-1;
}
if(start2<n&&end2>=n){
end2=n-1;
}这样我们就可以很好的实现我们的操作
边栏推荐
- LabVIEW controls Arduino to realize ultrasonic ranging (advanced chapter-5)
- Supplementary questions for the training ground on September 11, 2021
- UML系列文章(29)体系结构建模---模式和框架
- 相对完善的单例模式
- Analysis on the development history and market development status of China's system integration industry in 2020 [figure]
- table_ Display status
- Redis data type (string)
- LaTex实战笔记 3-宏包与控制命令
- RPA+低代码为何是加速财务数字化转型之利器?
- Endnotex9 introduction and basic tutorial instructions
猜你喜欢

Leetcode-76- minimum covering substring

Only 38 years old! Zhou Chuan, a researcher of the Chinese Academy of Sciences, died unfortunately. Rao Yi sent a document to mourn: he guided me when he was still my student

Servlet get form data

Apache local multi port configuration

LeetCode-32-最长有效括号

联调这夜,我把同事打了...

Answer fans' questions | count the number and frequency of letters in the text

Carry and walk with you. Have you ever seen a "palm sized" weather station?

JVM | runtime data area; Program counter (PC register);

LabVIEW控制Arduino实现红外测距(进阶篇—6)
随机推荐
类和对象(2)
LeetCode-32-最长有效括号
Redis basic data type (Zset) ordered collection
Hangzhou Electric Zhongchao 91006 guess the weight
焕新升级 | 创新,从云商店开始
EndnoteX9簡介及基本教程使用說明
【历史上的今天】6 月 11 日:蒙特卡罗方法的共同发明者出生;谷歌推出 Google 地球;谷歌收购 Waze
How to manually send events exposed by SAP commerce cloud mock application using SAP kyma console
JVM | runtime data area; Program counter (PC register);
[Part 16] copyonwritearraylist source code analysis and application details [key]
JVM | local method interface; Native Method Stack
BZOJ3189 : [Coci2011] Slika
bzoj3188 Upit
八、BOM - 章节课后练习题及答案
Leetcode-32- longest valid bracket
实验10 Bezier曲线生成-实验提高-交互式生成B样条曲线
Leetcode-104- maximum depth of binary tree
LabVIEW Arduino electronic weighing system (project Part-1)
Building a custom CNN model: identifying covid-19
2021 Niuke multi school 5 double strings