• 浅谈归并排序


    这是一个一(hu)本(shuo)正(ba)经(dao)的浅谈:

    首先归并排序是什么?

    归并排序就是归并排序啊!(天天瞎bb的我)

    简单说一下我的理解:

    这是分开的部分(以上)。

    这是合并的部分(以上)。

    为什么要用它呢?

    因为我闲得慌。

    归并排序可以说是最稳定的一种排序,并且它的时间复杂度为O(nlog_{} n)。

    相较于其他的排序,归并排序也有它的优点,即在处理大数据时。

    并且还可以用归并排序来计算逆序对。

    它的套路是什么呢?

    瞎几把乱打就对了。

    归并排序有着分治的思想,即先把无序对中间折半,分成左右两份子序对,再分解,直到每个子序对中只剩一个元素。

    逆序对就是数列中任意两个数满足大的在前,小的在后的组合。如果将这些逆序对都调整成顺序(即小的在前,大的在后),那么整个数列就会显得有序。冒泡排序就是

    通过消除这些逆序对来排序的,那么交换的次数就是逆序对的个数。

     如果你看懂了,恭喜,你已经异于常人。

    可以A掉这两道可爱的luogu题了:

    主要就是更改一下输出方式就可以啦~

    1.SP9722 CODESPTB - Insertion Sort

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    int k,n,ans=0;
    int a[500100],b[500100];
    void merge_sort(int l,int r) {
        if(l==r)return ;//一个数不用排
        int m=(l+r)>>1;
        merge_sort(l,m);
        merge_sort(m+1,r);
        int i=l,j=m+1,k=0;//i左边最小位置,j右边最小位置
        while(i<=m&&j<=r)
            if(a[i]<=a[j])b[++k]=a[i++];
            else ans+=m-i+1,b[++k]=a[j++];//加入右半段时,逆序对数增加
        while(i<=m)b[++k]=a[i++];//加入左边剩余的数
        while(j<=r)b[++k]=a[j++];//加入右边剩余的数
        for(i=1; i<=k; i++)a[l+i-1]=b[i];
    }
    int main() {
        scanf("%d",&k);
        for(int i=1; i<=k; i++) {
            ans=0;
            scanf("%d",&n);
            for(int i=1; i<=n; i++)
                scanf("%d",&a[i]);
            merge_sort(1,n);
            printf("%d
    ",ans);
        }
        return 0;
    }

    2.SP25784 BUBBLESORT - Bubble Sort

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    int k,n,ans=0;
    int a[50010],b[50010];//a原数组,b暂存数组 
    void merge_sort(int l,int r) {//归并 
        if(l==r)return ;//一个数不用排
        int m=(l+r)>>1;
        merge_sort(l,m);//排序左边 
        merge_sort(m+1,r);//排序右边  
        int i=l,j=m+1,k=l;//i左边最小位置,j右边最小位置
        while(i<=m&&j<=r){
            if(a[i]<=a[j])b[k++]=a[i++];
            else b[k++]=a[j++],ans= (ans+m-i+1)%10000007;//加入右半段时,逆序对数增加
        }
        while(i<=m)b[k++]=a[i++];//加入左边剩余的数
        while(j<=r)b[k++]=a[j++];//加入右边剩余的数
        for(int p=l; p<=r; ++p) a[p]=b[p],b[p]=0;//从暂存数组中赋值 
    }
    int main() {
        scanf("%d",&k);
        for(int j=1; j<=k; ++j) {
            scanf("%d",&n);
            for(int i=1; i<=n; ++i)    
            scanf("%d",&a[i]);
            ans=0;
            merge_sort(1,n);
            printf( "Case %d: %d
    ", k, ans );
        }
        return 0;
    }

    排序只用猴排。

    树只用八叉树。

  • 相关阅读:
    1234D.Distinct Characters Queries(树状数组)
    1217C.The Number of Good Substrings(思维)
    1217B.Zmei Gorynich(思维)
    1213D2.Equalizing by Division(hard version)(图论)
    CentOS7.5搭建Hadoop2.7.6完全分布式集群
    CentOS7.5搭建spark2.3.1集群
    CentOS7.5搭建Hive2.3.3
    【Java入门】JDK安装和环境变量配置(Win7版)
    python第三方库大全
    Python常用模块大全
  • 原文地址:https://www.cnblogs.com/morbidity/p/10762669.html
Copyright © 2020-2023  润新知