归并排序的核心思想:即从最小单位的元素开始两两归并(2路归并)
- 将要排序的数组中分成 n/2 个单个元素序列(n为数组的大小,单个元素的序列自然是有序的)
- 接着通过两两比较,将每两个有序的序列组成一个新的有序序列(两个元素的)(如果数组大小的奇数的话,那么会剩下一个1个大小的序列)
- 然后又将新的有序序列继续进行排序组成新的有序序列(四个元素、或三个元素).....直至组成完整的有序序列。
归并的过程中每次都需要借助数组来完成排序,因此比较占用内存。
时间复杂度:O(nlogn)
#include"stdio.h"
void MergeSort(int arr[],int L,int R);
void Merge(int arr[],int L,int M,int R);
void print(int arr[],int len){
for(int i=0;i<len;i++){
printf("%d ",arr[i]);
}
}
void MergeSort(int arr[],int L,int R){
if(L==R){
return;
}
int mid = (L+R)/2; //因为除法的结果是偏向左边的,这里的折中遇到L+1=R的情况时,结果就是mid = L
//二分
MergeSort(arr,L,mid);
MergeSort(arr,mid+1,R);
//归并
Merge(arr,L,mid,R);
}
void Merge(int arr[],int L,int M,int R){
int i = L;
int j = M+1;
int temp[R-L+1]; //创建合并数组(注意数组的大小)
int k = 0; //合并数组的下标
while(i<=M&&j<=R){ //由于左右两部分的数组是有序数组
if(arr[i]<arr[j]) //故只用从第一位开始逐位比较,较小值放入合并数组中
temp[k++] = arr[i++];
else
temp[k++] = arr[j++];
}
while(i<=M){ //将左边剩余的数据依次填进合并数组
temp[k++] = arr[i++];
}
while(j<=R){ //将右边剩余的数据依次填进合并数组
temp[k++] = arr[j++];
}
for(int h=0;h<k;h++){ //将创建的合并数组赋值回arr数组
arr[L+h] = temp[h];
}
}
int main(){
int a[] = {10,50,40,90,80,20,60,30,70,100};
int len = sizeof(a)/sizeof(int);
MergeSort(a,0,len-1);
print(a,len);
return 0;
}
参考博文:https://www.jianshu.com/p/33cffa1ce613