排序算法
给某个很笨的人准备的
一,sort,时间复杂度0(nlogn),小于1e7差不多都可以用,可以用于排序次数比较少的时候;
1,sort是给数组排序用的,可以直接调用C++里面的函数使用,记住,是C++别在给我用c,而且还要加上#include<algorithm>
用法一,直接使用,是从小到大排序
int a[[1005];
sort(a,a+n);//n指的是要排序的长度,从0排到n-1,总共n个数字
//也可以sort(a+k,a+k+n) 这个的话就是从第k个数字开始排,排到第n+k个数字
用法二,给定条件排序,比如从大到小,就要写一个判断函数
int a[1004];
bool cmp(int x,int y)
{
return x >y ; //只有当x>y的时候才是真,所以是从大到小排序的。 要是想从小到大,return x<y 就好了
}
sort(a,a+n,cmp); //和之前使用一样,后面加了个cmp就是,就是给定条件判断了
用法三,给结构体排序,其实也就是和用法二差不多
struct node
{
int num;
int id;
}a[10005];
bool cmp(node x,node y)
{
return x.num<y.num; //这个就是将结构体,以num的值进行排序,num小的在前面,要是想以其他值排,换就可以了,从大到小还是从小到大,大于号和小于号自己用;
}
sort(a,a+n,cmp); //这样就排好了
2,优先队列排序,时间复杂度0(nlogn),用于排序次数比较多的时候,直接推进去就会帮你排序好;
1,直接单个数字,字母进行排序
从大到小priority_queue<int> v;
从小到大priority_queue<int,vector<int>,greater<int> >v;
2,排结构体
#include<queue>
struct node {
int x, y;
friend bool operator < (node a, node b)
{
return a.x > b.x; //结构体中,根据x进行排序,x小的优先级高
//这个和sort的刚好相反
//不难理解,定义的是小于号,而返回的是x大的就是真,说明x越大 就越小
}
};
priority_queue<node>v;
3桶排序,时间复杂度O(n+m),n是数据个数,m是数据范围;用于数据很多,但是数据范围却不大的情况
意思是,把数据相同的,放进同一个桶里面,然后只需要对桶进行排序;
其实实现起来很简单,就是开一个数据范围大小的数组,然后输入数据,遇上那个就在数组力加一,然后全部输出就可以了
int a[N];//N是数据的范围
mm(a,0);//把数组里面的都变成0;
int n;
scf(n);
rep(i,0,n)
{
int x;
scf(x);
a[x]++;
}
rep(i,0,N+1)
{
while(a[i]--)
pf("%d ",i);
}
4,归并排序
就是把一个数组调用递归,然后一直二分,然后再组合再一起,时间复杂度O(nlogn).另外也可以用来求逆序对
过程图
#include<bits/stdc++.h>
#define sf scanf
#define scf(x) scanf("%d",&x)
#define scff(x,y) scanf("%d%d",&x,&y)
#define scfff(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define vi vector<int>
#define mp make_pair
#define pf printf
#define prf(x) printf("%d\n",x)
#define mm(x,b) memset((x),(b),sizeof(x))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const double eps=1e-6;
const double pi=acos(-1.0);
const int inf=0xfffffff;
const int N=1e5+7;
void merge(int a[],int l,int mid,int r)
{
int b[r-l+1]; //开辅助空间存原来的数,在把数字排好放回原数组
int pos1=l,pos2=mid+1; //两个指针位置
rep(i,l,r+1) b[i-l]=a[i]; //复制
rep(i,l,r+1)
{
if(pos1>mid) a[i]=b[pos2++-l];
else if(pos2>r) a[i]=b[pos1++-l];//以上两种是如果有一边已经放完了
else //如果还没放完
{
if(b[pos1-l]>b[pos2-l]) //右边小,把右边的数字插入
a[i]=b[pos2++-l];
else //左边小,把左边的数字放进去
a[i]=b[pos1++-l];
}
}
}
void msort(int a[],int l,int r)
{
if(l==r) return; //如果只有一个数字就回
int mid=(l+r)>>1;
msort(a,l,mid);
msort(a,mid+1,r);//分开排序
merge(a,l,mid,r);//组合再一起,顺便求逆序对的数量
}
int main()
{
int a[N],n;
while(~sf("%d",&n))
{
rep(i,0,n)
scf(a[i]);
msort(a,0,n-1);
rep(i,0,n)
cout<<a[i]<<" ";
cout<<endl;
}
}