排序算法

给某个很笨的人准备的

一,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).另外也可以用来求逆序对
过程图
1329647-20181115205453105-334185455.png

#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;
    }
}

转载于:https://www.cnblogs.com/wzl19981116/p/9740426.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值