歸併排序

定義

       歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併。

思路描述

把一個數組細分成單個元素,每個元素看做一個數組,在把這些元素數組按順序不斷合併,1個和併成2個,2個合併成4個…直到全部合併完成。 
如: 
圖片樣式

用途

1.排序 : 時間複雜度 O(n log n) ,空間複雜度 O(n) 。
2.求逆序對數:這也是歸併排序的主要用途

主要思想:   遞歸

優點比較:  歸併排序的比較次數小於快速排序的比較次數,移動次數一般多於快速排序的移動次數。                                                   (速度僅次於快速排序,爲穩定排序算法,一般用於對總體無序,但是各子項相對有序的數列) 

代碼如下(求逆序對數):

#include<cstdio>
const int MAXN=200005;
int n, a[MAXN], temp[MAXN];//數組a是輸入的數組,temp數組是最後排完序的數組
long long ans;
void count(int l, int r)
{
    if(r == l)
        return ;//結束條件
    int m = (l + r) >> 1;//相當於m = (l + r) / 2;
    count(l, m);//遞歸
    count(m + 1, r);//二分查找(遞歸)
    int i = l, j = m + 1, k = l;//i從左一半的第一個開始,j從右一半的第一個開始,k是數組temp的下表
    while(j <= r || i <= m)
    {
        if(j > r || (i <= m && a[i] <= a[j]))//當右半邊沒有數了或左半邊有數並且它的數比右半邊小時,執行它
            temp[k++] = a[i++];
        else
            temp[k++] = a[j++], ans += m - i + 1;
    }
    for(i = l; i <= r; i++)
        a[i] = temp[i];
}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    count(1, n);//調用函數
    printf("%lld", ans);//輸出
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章