歸併排序

歸併排序是一種分治策略。

將一串序列從中間分開,分爲low-mid,mid+1-high兩部分子序列。這是分解。

將子序列排序,並把排序後子序列重新複製給原數組。這是合併。

對子序列不斷遞歸調用,直到子序列個數爲1。數量爲1不再排序,直接將該數賦值給原數組。

例如一個序列 n=10

1 3 9 0 5 8 4 2 7 6

分解過程:1.  1-3-9-0-5 , 8-4-2-7-6

                 2.  1-3-9 , 0-5 ,8-4-2 ,7-6

                 3.  1-3 , 9 , 0 , 5 , 8-4 ,  2 ,7 ,6

                

代碼:

#include <iostream>
using namespace std;
void Merge(int *p,int low,int mid,int high)    //需要合併的數組,初始位置,中間位置,末尾位置
{
    int *q = new int [high - low +1];        //申請輔助數組
    int i=low,j=mid+1,k=0;
    while(i<=mid && j<=high)
    {
        if(p[i] < p[j])
        {
            q[k] = p[i];
            i++;
        }
        else
        {
            q[k] = p[j];
            j++;
        }
        k++;
    }

    while(i<=mid)
    {
        q[k] = p[i];
        i++,k++;
    }
    while(j<=high)
    {
        q[k] = p[j];
        j++,k++;
    }

    for(i=low,k=0;i<=high;i++,k++)
        p[i] = q[k];
}

void MergeSort(int *p,int low ,int high)    
{
    int mid;
    if(low < high)
    {
        mid = (low + high)/2;
        MergeSort(p,low,mid);    //遞歸調用
        MergeSort(p,mid+1,high);
        Merge(p,low,mid,high);
    }
}

int main()
{
    int n,i;
    cin>>n;
    int p[n];
    for(i=0;i<n;i++)
        cin>>p[i];
    MergeSort(p,0,n-1);
    for(i=0;i<n;i++)
        cout<<p[i]<<" ";
    return 0;
}

時間複雜度的分析:

歸併排序的過程類似與構建一個二叉樹,對於具有N個數的序列,最終構成的二叉樹的的層數爲logN,自底向上解決時,每一層都要對這n個數排序一次,所以總的合併複雜度爲O(N*logN);

對於分解的複雜度,每一層的分解都是直接根據下標來分解,爲O(1),logN層就是 logN,最後總的時間複雜度還是O(N*logN)

發佈了112 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章