歸併排序(Merge sort)

歸併排序是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併。
歸併操作:
歸併操作(merge),也叫歸併算法,指的是將兩個順序序列合併成一個順序序列的方法。
如 設有數列{6,202,100,301,38,8,1}
初始狀態:6,202,100,301,38,8,1
第一次歸併後:{6,202},{100,301},{8,38},{1},比較次數:3;
第二次歸併後:{6,100,202,301},{1,8,38},比較次數:4;
第三次歸併後:{1,6,8,38,100,202,301},比較次數:4;
總的比較次數爲:3+4+4=11,;
逆序數爲14;
算法描述:
歸併操作的工作原理如下:
第一步:申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列
第二步:設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置
第三步:比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置
重複步驟3直到某一指針超出序列尾
將另一序列剩下的所有元素直接複製到合併序列尾

這裏寫代碼片
#include<stdio.h>
#include<stdlib.h>
void array_show(int* arr, int len);
void mergeSort(int a[], int n);
int main(int argc, char* argv[])
{
    int arr[10] = {4,3,8,5,2,1,6,0,7,9};
    array_show(arr, 10);
    mergeSort(arr, 10);
    putchar(10);
    array_show(arr, 10);

    system("pause");

    return 0;
}
void array_show(int* arr, int len)
{
    int i ;
    for(i = 0; i != len; i ++)
    {
        printf("%d ", arr[i]);
    }
}
void mergeTwoArray(int a[], int lena, int b[], int lenb)
{
    int* tmparray=new int[lena+lenb];
    int i=0, j=0, k=0;
    while(i<lena && j<lenb)
    {
        if(a[i]<b[j])
        {
            tmparray[k]=a[i];
            i++,k++;
        }
        else
        {
            tmparray[k]=b[j];
            j++,k++;
        }
    }
    while(i<lena)
    {
        tmparray[k]=a[i];
        i++,k++;
    }
    while(j<lenb)
    {
        tmparray[k]=b[j];
        j++,k++;
    }
    for(i=0; i<lena+lenb; i++)
    {
        a[i]=tmparray[i];
    }
    delete [] tmparray;
}
void mergeSort(int a[], int n)
{
    if(n>1)
    {
        int mid=n/2;
        int lena=mid;
        int lenb=n-mid;
        int* b=a+mid;
        mergeSort(a,lena);
        mergeSort(b,lenb);
        mergeTwoArray(a,lena,b,lenb);
    }
}

歸併排序是穩定的排序,即相等的元素的順序不會改變,速度僅次於快速排序。
時間複雜度爲O(nlogn) 這是該算法中最好、最壞和平均的時間性能。
空間複雜度爲 O(n),比較操作的次數介於(nlogn) / 2和nlogn - n + 1。
賦值操作的次數是(2nlogn)。
歸併算法的空間複雜度爲:0 (n)
歸併排序比較佔用內存,但卻是一種效率高且穩定的算法。

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