归并排序
时间限制:1秒 内存限制:32M
题目描述
归并排序是基于归并操作完成的,而一次归并操作是通过两个或两个以上的有序表合并成一个新的有序表完成的。常见的归并排序是2-路归并排序,其核心操作是将一维数组中前后相邻的两个有序序列归并成一个有序序列。
在本题中,读入一串整数,将其使用以上描述的2-路归并排序的方法从小到大排序,并输出。
输入描述
输入的第一行包含1个正整数n,表示共有n个整数需要参与排序。其中n不超过100000。
第二行包含n个用空格隔开的正整数,表示n个需要排序的整数。
输出描述
只有1行,包含n个整数,表示从小到大排序完毕的所有整数。
请在每个整数后输出一个空格,并请注意行尾输出换行。
样例
输入
10 2 8 4 6 1 10 7 3 5 9
输出
1 2 3 4 5 6 7 8 9 10
提示
在本题中,需要按照题目描述中的算法完成2-路归并排序的算法。
不难发现,2-路归并算法的时间复杂度为O(nlog2n),且需要和原始数据等数量的辅助空间。递归形式的2-路归并排序算法在形式上比较简洁,但是实用性较差。通常在需要使用归并排序的场合,往往使用非递归形式的归并排序。
与快速排序和堆排序相比,归并排序的特点在于其是一种稳定的排序方法。
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+5;
int a[N];
void merge(int l1,int r1,int l2,int r2){
int index=0,t[N];
int i=l1,j=l2;
while(i<=r1&&j<=r2){
if(a[i]<a[j]){
t[index++]=a[i++];
}
else{
t[index++]=a[j++];
}
}
while(i<=r1){
t[index++]=a[i++];
}
while(j<=r2){
t[index++]=a[j++];
}
for(int i=0;i<index;i++){
a[l1+i]=t[i];
}
}
void mergesort(int l,int r) {
if(l==r) {
return;
}
int mid=l+(r-l)/2;
mergesort(l,mid);
mergesort(mid+1,r);
merge(l,mid,mid+1,r);
}
int main() {
int n;
cin>>n;
for(int i=0; i<n; i++) {
cin>>a[i];
}
mergesort(0,n-1);
for(int i=0; i<n; i++) {
cout<<a[i]<<" ";
}
return 0;
}