给定你一个长度为 n 的整数数列。
请你使用归并排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n个整数(所有整数均在 1∼1091∼109 范围内),表示整个数列。
输出格式
输出共一行,包含 n个整数,表示排好序的数列。
数据范围
1≤n≤1000001≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
代码如下:
#include<iostream>
using namespace std;
const int N=1000010;
int n;
int q[N],tmp[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]){
tmp[k++]=q[i++];
}else{
tmp[k++]=q[j++];
}
}
while(i<=mid){
tmp[k++]=q[i++];
}
while(j<=r){
tmp[k++]=q[j++];
}
for(i=l,j=0;i<=r;i++,j++){
q[i]=tmp[j];
}
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&q[i]);
}
merge_sort(q,0,n-1);
for(int i=0;i<n;i++){
printf("%d ",q[i]);
}
return 0;
}
-
merge_sort
函数实现了归并排序的核心逻辑。它接受一个数组q
、左边界l
和右边界r
作为参数,对数组q
的子区间[l, r]
进行排序。 -
在
merge_sort
函数中,如果左边界l
大于等于右边界r
,则表示子区间长度为0或者1,无需再继续划分和排序,直接返回。 -
否则,计算子区间的中间位置
mid
,然后递归地对左半部分[l, mid]
和右半部分[mid+1, r]
进行排序。 -
接下来是合并两个已排序的子数组的过程。使用
tmp
数组暂存合并后的结果。使用k
记录合并后数组的当前位置,i
记录左半部分的当前位置,j
记录右半部分的当前位置。 -
在合并过程中,比较左右两部分的当前元素,将较小的元素放入
tmp
数组中,并将对应的索引向后移动。 -
将剩余的未处理元素直接放入
tmp
数组中。 -
最后,将
tmp
数组中的元素复制回原数组q
,完成合并排序过程。 -
在
main
函数中,读取输入的数组大小n
和数组元素,并调用merge_sort
对数组进行排序。最后输出排好序的数组。
这就是整个归并排序算法的实现过程。它的时间复杂度为 O(nlogn),是一种高效的排序算法。