排序

题目链接

P1177 【模板】快速排序

image

快速排序

  • 时间复杂度:\(O(nlogn)\)
  • 空间复杂度:\(O(1)\)
#include<bits/stdc++.h>
using namespace std;
void quick_sort(int a[],int l,int r)
{
    if(l>=r)return ;
    int i=l-1,j=r+1,x=a[l+r>>1];
    while(i<j)
    {
        do i++;while(a[i]<x);
        do j--;while(a[j]>x);
        if(i<j)swap(a[i],a[j]);
    }
    quick_sort(a,l,j),quick_sort(a,j+1,r);
}
int n,a[1000005];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    quick_sort(a,1,n);
    for(int i=1;i<=n;i++)printf("%d ",a[i]);
    return 0;
}

快速选择

链接:786. 第k个数

  • 时间复杂度:\(O(n)\)
  • 空间复杂度:\(O(1)\)
#include<bits/stdc++.h>
using namespace std;
int a[100005],n,k;
int quick_sort(int a[],int l,int r,int k)
{
    if(l==r)return a[k];
    int i=l-1,j=r+1,x=a[l+r>>1];
    while(i<j)
    {
        do i++;while(a[i]<x);
        do j--;while(a[j]>x);
        if(i<j)swap(a[i],a[j]);
    }
    if(k<=j)return quick_sort(a,l,j,k);
    return quick_sort(a,j+1,r,k);
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    printf("%d",quick_sort(a,1,n,k));
    return 0;
}

归并排序

  • 时间复杂度:\(O(nlogn)\)
  • 空间复杂度:\(O(n)\)
#include<bits/stdc++.h>
using namespace std;
int n,a[1000005],tmp[1000005];
void merge_sort(int a[],int l,int r)
{
    if(l>=r)return ;
    int mid=l+r>>1;
    merge_sort(a,l,mid),merge_sort(a,mid+1,r);
    int i=l,j=mid+1,k=0;
    while(i<=mid&&j<=r)
        if(a[i]<a[j])tmp[k++]=a[i++];
        else
            tmp[k++]=a[j++];
    while(i<=mid)tmp[k++]=a[i++];
    while(j<=r)tmp[k++]=a[j++];
    for(int i=l,j=0;i<=r;i++,j++)a[i]=tmp[j];
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    merge_sort(a,1,n);
    for(int i=1;i<=n;i++)printf("%d ",a[i]);
    return 0;
}

逆序对的数量

链接:788. 逆序对的数量

  • 时间复杂度:\(O(nlogn)\)
  • 空间复杂度:\(O(n)\)
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
using LL=long long;
int n,a[N],t[N];
LL merge_sort(int a[],int l,int r)
{
    if(l>=r)return 0;
    int mid=l+r>>1;
    LL res=merge_sort(a,l,mid)+merge_sort(a,mid+1,r);
    int i=l,j=mid+1,k=0;
    while(i<=mid&&j<=r)
    {
        if(a[i]<=a[j])t[k++]=a[i++];
        else
            res+=mid-i+1,t[k++]=a[j++];
    }
    while(i<=mid)t[k++]=a[i++];
    while(j<=r)t[k++]=a[j++];
    for(int i=l,j=0;i<=r;i++,j++)a[i]=t[j];
    return res;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    printf("%lld",merge_sort(a,1,n));
    return 0;
}

堆排序

  • 时间复杂度:\(O(nlogn)\)
  • 空间复杂度:\(O(1)\)
#include<bits/stdc++.h>
using namespace std;
int n,cnt,a[100005];
void down(int u)
{
    int t=u;
    if(u*2<=cnt&&a[t]>a[u*2])t=u*2;
    if(u*2+1<=cnt&&a[t]>a[u*2+1])t=u*2+1;
    if(u!=t)
    {
        swap(a[t],a[u]);
        down(t);
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    cnt=n;
    for(int i=n/2;i;i--)down(i);
    for(int i=1;i<=n;i++)
    {
        printf("%d%c",a[1],i<n?' ':'\0');
        a[1]=a[cnt--];
        down(1);
    }
    return 0;
}

模拟堆

链接:839. 模拟堆

操作
1 插入一个数 \(x\)
2 输出最小值
3 删除最小值
4 删除第 \(k\) 个插入的数
5 修改第 \(k\) 个插入的数,将其变为 \(x\)
  • 时间复杂度:\(O(nlogn)\)
  • 空间复杂度:\(O(n)\)
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,cnt,k,x;
int h[N],hp[N],ph[N];
void heap_swap(int a,int b)
{
    swap(ph[hp[a]],ph[hp[b]]);
    swap(hp[a],hp[b]);
    swap(h[a],h[b]);
}
void down(int u)
{
    int t=u;
    if(2*u<=cnt&&h[t]>h[2*u])t=2*u;
    if(2*u+1<=cnt&&h[t]>h[2*u+1])t=2*u+1;
    if(u!=t)
    {
        heap_swap(u,t);
        down(t);
    }
}
void up(int u)
{
    if(u/2>=1&&h[u]<h[u/2])
    {
        heap_swap(u,u/2);
        up(u/2);
    }
}
int main()
{
    scanf("%d",&n);
    while(n--)
    {
        char op[5];
        scanf("%s",op);
        if(!strcmp(op,"I"))
        {
            scanf("%d",&x);
            h[++cnt]=x;
            m++;
            ph[m]=cnt,hp[cnt]=m;
            up(cnt);
        }
        else if(!strcmp(op,"PM"))
            printf("%d\n",h[1]);
        else if(!strcmp(op,"DM"))
        {
            heap_swap(1,cnt--);
            down(1);
        }
        else if(!strcmp(op,"D"))
        {
            scanf("%d",&k);
            k=ph[k];
            heap_swap(k,cnt--);
            down(k),up(k);
        }
        else
        {
            scanf("%d%d",&k,&x);
            k=ph[k];
            h[k]=x;
            down(k),up(k);
        }
    }
    return 0;
}

基数排序

\({\displaystyle n}\)是排序元素个数,\({\displaystyle k}\)是数字位数

  • 时间复杂度:\(O(kn)\)
  • 空间复杂度:\(O(n+k)\)
#include<bits/stdc++.h>
using namespace std;
int a[100005],tmp[100005],cnt[10],n;
int max_bit(int a[],int n)
{
    int d=1,p=10;
    for(int i=1;i<=n;i++)
        while(a[i]>=p)
        {
            d++;
            p*=10;
        }
    return d;
}
void radix_sort(int a[],int n)
{
    int d=max_bit(a,n);
    int radix=1;
    for(int i=1;i<=d;i++)
    {
        memset(cnt,0,sizeof cnt);
        for(int j=1;j<=n;j++)cnt[(a[j]/radix)%10]++;
        for(int j=1;j<10;j++)cnt[j]=cnt[j]+cnt[j-1];
        for(int j=n;j;j--)
        {
            int k=(a[j]/radix)%10;
            tmp[cnt[k]]=a[j];
            cnt[k]--;
        }
        memcpy(a,tmp,sizeof tmp);
        radix*=10;
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    radix_sort(a,n);
    for(int i=1;i<=n;i++)printf("%d ",a[i]);
    return 0;
}

桶排序

这里的c++实现与最优有些出入~

  • 时间复杂度:\(O(n+k)\)
  • 空间复杂度:\(O(n+k)\)
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> a;
void bucket_sort(vector<int> &a)
{
    int mx=a[0],mn=a[0];
    for(int &i:a)mx=max(mx,i),mn=min(mn,i);
    int d=mx-mn;
    int bucket_num=a.size();
    if(bucket_num==1)return ;
    vector<list<int>> lst(bucket_num);
    for(int &i:a)
    {
        int idx=(i-mn)/(d/(bucket_num-1));
        lst[idx].push_back(i);
    }
    a.clear();
    for(auto &bucket:lst)
    {
        vector<int> t(bucket.begin(),bucket.end());
        sort(t.begin(),t.end());
        a.insert(a.end(),t.begin(),t.end());
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        a.push_back(x);
    }
    bucket_sort(a);
    for(int &i:a)printf("%d ",i);
    return 0;
}
posted @ 2021-09-17 23:31  zyy2001  阅读(39)  评论(0编辑  收藏  举报