zoukankan      html  css  js  c++  java
  • 排序

    summary:

    用好(sort)万事大吉

    可以康康归并排序逆序对——当然还是觉得树状数组求逆序对更简单

    冒泡排序

    原理

    冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。

    https://zhuanlan.zhihu.com/p/61094267

    复杂度最好(O(n))——本身有序

    最差(O(N^2))——本身逆序

    优化

    优化

    例题

    https://www.luogu.com.cn/problem/P4378

    Description

    进行多少次冒泡排序

    Solution

    转载自https://www.cnblogs.com/Hs-black/p/11626111.html

    博客后还有别的证明方法

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N=4e6+10;
    inline int read() {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    int n,m,cnt;
    int b[N],c[N];
    pair<int,int>a[N];
    void update(int x){
        for(;x<=N;x+=x&(-x))
            c[x]++;
    }
    int query(int x){
        int res=0;
        for(;x;x-=x&(-x))
            res+=c[x];
        return res;
    }
    int ans;
    bool cmp(pair<int,int> a,pair<int,int> b){
        return a.second<b.second;
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++) a[i]=make_pair(read(),i);
        sort(a+1,a+1+n);
        for(int i=1;i<=n;i++) a[i].first=i;
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;i++){
            update(a[i].first);
            ans=max(ans,i-query(a[i].first));
        }
        printf("%d
    ",ans+1);
        return 0;
    }
    

    直接插入排序

    类似于斗地主整理手牌

    希尔排序

    没啥用吧

    快速排序

    常用的

    一趟排序基准元素就在它正确的位置,然后递归处理它前面的和后面的,

    void qsort(int a[],int l,int r){
        if((l<r){
            int i=l,j=r,x=a[l];
            while(i<j){
                while(i<j&&a[j]>=x) j--;
                if(i<j) a[i++]=a[j];
                while(i<j&&a[i]<x) i++;
                if(i<j) a[j--]=a[i];
            }
            a[i]=x;
            qsort(a,l,i-1);
            qsort(a,i+l,r);
        }
    }
    

    一般用好(sort)就万事大吉

    选择排序

    直观

    归并排序

    (O(nlogn))

    [T(n)=2*T(n/2)+n;\ 设m=2^k,k=logm;则有 T(n)=2*T(n/2)+n=2*T(2*T(n/4)+n/2)+n...\ 2^k*T(1)+k*m=m+m*logm;\ ]

    递归树(log)层,每层合并是(n)

    求逆序对

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N=1e6;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    int n;
    long long a[N],c[N],ans;
    void merge(int l,int r){
        if(l>=r) return;
        int mid=(l+r)>>1;
        merge(l,mid);
        merge(mid+1,r);
        for(int i=l;i<=r;i++) c[i]=a[i];
        int i=l,j=mid+1;
        for(int k=l;k<=r;k++){
            if(i>mid) a[k]=c[j++];
            else if(j>r) a[k]=c[i++];
            else if(c[i]>c[j]) a[k]=c[j++],ans+=mid-i+1;//和j产生的逆序对数量
            else a[k]=c[i++];
        }
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        merge(1,n);
        printf("%lld
    ",ans);
        return 0;
    } 
    
    
    
  • 相关阅读:
    dede图片横向滚动
    dede各种运用[转]
    PROFIBUS-DP现场总线的结构及应用
    51单片机的中断优先级及中断嵌套
    WPF里面制作圆角文本框
    【转】什么叫51单片机最小系统
    【转】(C#)OPC客户端源码
    路漫漫其修远兮,吾要上下左右前后而求索
    二叉树创建为什么用二级指针
    无向图的邻接表创建
  • 原文地址:https://www.cnblogs.com/ke-xin/p/13544631.html
Copyright © 2011-2022 走看看