P1177 【模板】排序
前言
排序模板题,到我大显身手(并不存在的)的时候了,写三种方法,复习一下快排吧。
题目
题目描述
将读入的 N N N 个数从小到大排序后输出。
输入格式
第一行为一个正整数 N N N。
第二行包含 N N N 个空格隔开的正整数 a i a_i ai,为你需要进行排序的数。
输出格式
将给定的 N N N 个数从小到大输出,数之间空格隔开,行末换行且无空格。
样例 #1
样例输入 #1
5
4 2 4 5 1
样例输出 #1
1 2 4 4 5
提示
对于 20 % 20\% 20% 的数据,有 1 ≤ N ≤ 1 0 3 1 \leq N \leq 10^3 1≤N≤103;
对于 100 % 100\% 100% 的数据,有 1 ≤ N ≤ 1 0 5 1 \leq N \leq 10^5 1≤N≤105, 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1≤ai≤109。
题目分析
没什么好说的就是排序题,排序也是老生常谈了,别人的博客比我更好
注意事项
无
代码
1.经典sort函数(最简单)
需要引用#include<algorithm>
头文件或者#include<bits/stdc++.h>
万能头
注意这边sort(a,a+n)是给a[0]~a[n-1]排序。
一般排序
#include<bits/stdc++.h>
using namespace std;
int a[2000000],n;//数组要记得开大
int main()
{
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
sort(a,a+n); //sort排序
for(int i=0;i<n;i++)cout<<a[i]<<" ";
return 0;
}
结构体排序
例如L1-056猜数字可以写成如下
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
struct num//定义结构体
{
char name[10];//姓名
int num;//所猜数字
double cha;//与平均值一半的差值
};
bool cmp(num a, num b){//cmp函数
return a.cha < b.cha;
}
int main()
{
struct num a[10010];
int n;
double sum = 0;
cin >> n;
for(int i = 0; i < n; i ++)//输入
{
cin >> a[i].name;
cin >> a[i].num;
sum += a[i].num;
}
sum /= n*2;
for(int i = 0; i < n; i ++)//求每个的差值
{
a[i].cha = fabs(a[i].num - sum);
}
sort(a, a + n, cmp);//排序
cout << (int) sum <<' '<< a[0].name;
return 0;
}
2.冒泡排序(最易懂简单的)
作为最基础的排序方法(但是本题会超时)
#include<bits/stdc++.h>
using namespace std;
int a[2000000],n,t;//数组要记得开大
int main()
{
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<n-1;i++)
for(int j=0;j<n-i-1;j++)
{
if(a[j]>a[j+1]){
t=a[j+1];
a[j+1]=a[j];
a[j]=t;
}
}
for(int i=0;i<n;i++)cout<<a[i]<<" ";
return 0;
}
3.冒泡排序2(我感觉最好背的代码,也是我最喜欢的排序)
作为最基础的排序方法(但是本题会超时)
虽然本方法效率一般,但是好好记又好写,我超喜欢的
#include<bits/stdc++.h>
using namespace std;
int a[2000000],n,t;//数组要记得开大
int main()
{
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++)
{
if(a[i]>a[j]){
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
for(int i=0;i<n;i++)cout<<a[i]<<" ";
return 0;
}
4.快速排序(经典算法,综合最优)
一般用函数偷懒,不过如果是C就没函数得自食其力了。我用C写一个快排吧。
太久没写已经忘记头文件是什么了。
自己写的但是很垃圾的快排(原理是快排,但是速度没有)
#include<stdio.h>
int a[2000000]={0},b[2000000]={0};
void quicksort(int start,int end){
if(end-start<2)
return;
//直接使用start作为比较的数
int t=a[start],point=start+1,p=0,q=end-start;
while(point!=end+1){//遍历整个需要快排的,相当于for
if(a[point]<=t)
b[p++]=a[point++];//小于的情况
else
b[q--]=a[point++];//大于
}
b[p]=t;
for(int i=0;i<end-start+1;i++){//复制过来
a[start+i]=b[i];
}
quicksort(start,p-1);//继续排序前面的
quicksort(p+1,end);
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
quicksort(0,n-1);//进入快排
for(int i=0;i<n;i++)
printf("%d ",a[i]);
return 0
}
改进版的自己写的快排
标准模板快排
快排函数,见第一种排序方法
略
快排大致意思是选取一个数,这个数在中间,然后比它小的在左边,比它大的放右边,然后重复缩小空间,排序的效率其实就在于选取的这个数是否为数值比较居中的数,中位数为最佳,所以快排也有改进的算法,在面对更大规模的数组时,往往可以先挑选几个数选择这几个数的中位数来作为第一个比较的数。