题目描述
利用快速排序算法将读入的 NN 个数从小到大排序后输出。
快速排序是信息学竞赛的必备算法之一。对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成。(C++ 选手请不要试图使用 STL,虽然你可以使用 sort 一遍过,但是你并没有掌握快速排序算法的精髓。)
输入格式
第 11 行为一个正整数 NN,第 22 行包含 NN 个空格隔开的正整数 a_iai,为你需要进行排序的数,数据保证了 a_iai 不超过 10^9109。
输出格式
将给定的 NN 个数从小到大输出,数之间空格隔开,行末换行且无空格。
答案如下:
思路是分治。
这是一种稳定的排序方式
- 中间为分界点
- 递归左右两侧
- 归并——合二为一,和快速排序的方法类似,双指针算法,左侧和右侧的不断移动,指针所指的数值小的那一个存入新数组中
#include<iostream>
using namespace std;
int res[1000010];//暂时存放数值的数组
int a[1000010];//输入数据的数组
void merge_sort(int b[],int l,int r)
{
if(l>=r) return;//如果只有一个数据,直接返回
int mid=(l+r)/2;//从中间分开
merge_sort(b,l,mid);//左侧递归
merge_sort(b,mid+1,r);//右侧递归
int k=0;//设置一个数字,方便在res数组中存入数值
int i=l;//左侧部分的指针
int j=mid+1;//右侧部分的指针
while(i<=mid&&j<=r) //两个指针跑起来
{
if(b[i]<=b[j]) res[k++]=b[i++];//两个指针所指数值之中小的那一个存入res数组中,同时指针接着向下走,k也不断走着,以便于存放下一个数值
else res[k++]=b[j++];
}
//两个指针一定有一个指针先走到终点,另一侧的数值本来就是排好队的,直接接入res数组中即可
while(i<=mid) res[k++]=b[i++];
while(j<=r) res[k++]=b[j++];
for(i=l,j=0;i<=r;i++,j++) b[i]=res[j];//将新数组中的数值返还给原来的数组
}
int main()
{
int n;
cin>>n;//输入需要排列的数的个数
for(int i=0;i<n;i++) scanf("%d",&a[i]);//输入各个数值
merge_sort(a,0,n-1);//执行函数
for(int i=0;i<n;i++) printf("%d ",a[i]);//输出排列好的数值
return 0;
}