淺談歸並排序


這是一個一(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\n",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\n", k, ans );
    }
    return 0;
}

 

 

排序只用猴排。

樹只用八叉樹。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM