归并排序主要用了分治与递归的思想,前期划分,后期合并,时间复杂度为nlogn
1、确定分界点 mid=(l+r)/2
2、递归排序
3、归并 — 合二为一
话不多说,上代码
#include<stdio.h>
#include<stdlib.h>//分配内存
void print_arr(int arr[],int n)//辅助函数,打印数组
{
for(int i=0;i<n;i++)
printf("%d",arr[i]);
putchar('\n');
}
//合并
void merge(int arr[],int tempArr[],int left,int mid,int right)
{
int l_pos=left;//标记左半区第一个未排序的元素
int r_pos=mid+1;//标记右半区第一个未排序的元素
int pos=left;//临时数组元素的下标
//合并
while(l_pos<=mid&&r_pos<=right)
{
if(arr[l_pos]<arr[r_pos])
tempArr[pos++]=arr[l_pos++];
else
tempArr[pos++]=arr[r_pos++];
}
//合并左半区剩余的元素
while(l_pos<=mid)
tempArr[pos++]=arr[l_pos++];
//合并右半区剩余的元素
while(r_pos<=right)
tempArr[pos++]=arr[r_pos++];
//把临时数组中合并后的元素复制回原来的数组
while(left<=right)
{
arr[left]=tempArr[left];
left++;
}
}
//归并排序
void msort(int arr[],int tempArr[],int left,int right)
{
//如果只有一个元素,那么就不用继续划分了
//因为一个元素的区域,它本身就是有序的
if(left<right)
{
//找中间点
int mid=(left+right)/2;
//递归划分左半区
msort(arr,tempArr,left,mid);
//递归划分右半区
msort(arr,tempArr,mid+1,right);
//归并已经排序好的部分
merge(arr,tempArr,left,mid,right);
}
}
//归并排序的入口
//主要进行辅助数组的分配和回收
void merge_sort(int arr[],int n)
{
//分配一个辅助数组
int *tempArr=(int*)malloc(n*sizeof(int));
if(tempArr)//辅助数组分配成功
{
msort(arr,tempArr,0,n-1);
free(tempArr);//使用完,释放空间
}
else
printf("error:failed to allocate memory");
}
int main(int argc,char const*argv[])
{
int arr[]={9,5,2,7,12,4,3,1,11};
int n=9;
print_arr(arr,n);
merge_sort(arr,n);
print_arr(arr,n);
return 0;
}
这里还有一个y总给的简洁版
#include<iostream>
using namespace std;
const int N=1000010;
int n;
int a[N],temp[N];
void merge_sort(int q[],int l,int r)
{
if(l>=r)return;
int mid=l+r>>1;
//递归划分
merge_sort(q,l,mid),merge_sort(q,mid+1,r);//递归划分
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r)
if(q[i]<=q[j])temp[k++]=q[i++];
else temp[k++]=q[j++];
while(i<=mid)temp[k++]=q[i++];//处理多余元素
while(j<=r)temp[k++]=q[j++];
for(i=l,j=0;i<=r;i++,j++)q[i]=temp[j];//把排序好的复制回元素组
//排序的区间是从 l 开始的,排完序后,将临时数组中的值拷会原数组中对应位置。
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
merge_sort(a,0,n-1);//归并排序merge_sort()内部 左右区间分解到只剩一个数 然后进行合并 往上传递
for(int i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}