给定你一个长度为 n
的整数数列。
请你对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n
。
第二行包含 n
个整数(所有整数均在 1∼109
范围内),表示整个数列。
输出格式
输出共一行,包含 n
个整数,表示排好序的数列。
数据范围
1≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int q[N];
int sz,w[N]; //merge_sort
void inser_sort() //直接插入排序 n^2 TLE
{
for(int i=1;i<n;i++) //遍历每一个位置
{
if(q[i-1]<=q[i]) continue;
int t=q[i],j=i;
while(q[j-1]>t&&j!=0) //如果后面的数t大于前面的,则后面的数t往前移,直到遍历到没有比t大的位置时停止
{
q[j]=q[j-1];
j--;
}
q[j]=t;
}
}
void binary_search_insert_sort() //折半插入排序 n^2 TLE
{
for(int i=1;i<n;i++)
{
if(q[i-1]<=q[i]) continue;
int t=q[i];
int l=0,r=i-1; //二分查找
while(l<r) //找到l=r的位置,q[l]>=t
{
int mid=(l+r)/2; //下取整,要得到的在l左边
if(q[mid]>t) r=mid;
else l=mid+1;
}
for(int j=i-1;j>=l;j--) q[j+1]=q[j];
q[l]=t;
}
}
void bubble_sort() //冒泡排序
{
for(int i=0;i<n-1;i++) //排n-1次
{
bool has_swap=false; //优化
for (int j=n-1; j>i; j-- ) //从后往前,找到i个小的数
if(q[j]<q[j-1])
{
swap(q[j],q[j-1]);
has_swap=true;
}
if(!has_swap) break; //如果没有交换,说明已经有序
}
}
void select_sort() //简单选择排序,每次选择出第i小的数到到第i位置
{
for(int i=0;i<n-1;i++)
{
int k=i; //用k记录最小数的位置
for(int j=i+1;j<n;j++)
if(q[j]<q[k])
k=j;
swap(q[i],q[k]);
}
}
void shell_sort() //希尔排序
{
for(int d=n/3;d;d= d==2?1:d/2) //d个一组,找d
{
for(int start=0;start<d;start++) //对每一组进行遍历
{
for(int i=start+d;i<n;i+=d) //划分每一组,进行组内直接插入排序,从前往后遍历
{
int t=q[i],j=i;
while(j!=start&&q[j-d]>t)
{
q[j]=q[j-d];
j-=d;
}
q[j]=t;
}
}
}
}
void quick_sort(int l,int r) //快速排序
{
if(l>=r) return;
int i=l-1,j=r+1,x=q[(l+r)/2]; //选取分组中间的数作为基数
while(i<j)
{
do i++;while(q[i]<x);
do j--;while(q[j]>x);
if(i<j) swap(q[i],q[j]);
}
quick_sort(l,j); //此时必须写j,否则[0,1]边界死循环 //写i要改成i-1,i x=q[(l+r+1)/2]或者q[r]
quick_sort(j+1,r);
}
void down(int u)
{
int t=u;
if(u*2<=sz&&q[u*2]>q[t]) t=u*2;
if(u*2+1<=sz&&q[u*2+1]>q[t]) t=u*2+1;
if(u!=t)
{
swap(q[u],q[t]);
down(t);
}
}
void heap_sort() //堆排序,下标一定要从1开始
{
sz=n;
for(int i=n/2;i;i--) down(i);
for(int i=0;i<n-1;i++)
{
swap(q[1],q[sz]);
sz--;
down(1;)
}
}
void merge_sort(int l,int r) //二路归并排序
{
if(l>=r) return;
int mid=(l+r)/2;
merge_sort(l,mid),merge_sort(mid+1,r);
int i=l,j=mid+1,k=0;
while(i<=mid&&j<=r) //双指针算法
{
if(q[i]<=q[j]) w[k++]=q[i++];
else w[k++]=q[j++];
}
while(i<=mid) w[k++]=q[i++]; //如果[mid+1,r]区间都小于[i,mid],这时将[i,mid]区间拼接到后面
while(j<=r) w[k++]=q[j++]; //如果[l,mid]区间都小于[j,r]区间,则将[j,r]拼接到后面
for(i=l,j=0;j<k;i++,j++) q[i]=w[j];
}
int main()
{
scanf("%d", &n);
for(int i=0;i<n;i++){
scanf("%d", &q[i]);
}
// inser_sort();
// binary_search_insert_sort();
// bubble_sort();
// select_sort();
// shell_sort();
// quick_sort(0,n-1);
// heap_sort();
merge_sort(0,n-1);
for(int i=0;i<n;i++) printf("%d ",q[i]);
return 0;
}