歸併排序(C++實現、遞歸、非遞歸)

(本博客旨在個人總結回顧)

1.概括

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

2.實現

C++遞歸和非遞歸實現:(一般遞歸轉爲非遞歸,可以使用stack實現)

// MergeSort.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

/*
 * @name   Sort(有序和排序都爲升序)
 * @brief  將左右爲有序的數組排序
 * @param  [in] int * pUnsortArray  左右兩部分已經爲有序的待排序數組
 * @param  [in] int nLeft  左下標
 * @param  [in] int nMid   中間下標 
 * @param  [in] int nRight 右下標
 * @param  [in] int * pSortArray    排序後放置的臨時數組
 * @return void
 */
 void Sort(int* pUnsortArray, int nLeft, int nMid, int nRight, int* pSortArray)
{
    int nBegin = nLeft;
    int nEnd = nRight;
    int nIndex1 = nLeft;
    int nIndex2 = nMid +1;
    while (nBegin <= nEnd)
    {
        if (nIndex1 <= nMid && nIndex2 <= nRight)
        {
            if (pUnsortArray[nIndex1] <= pUnsortArray[nIndex2])
            {
                pSortArray[nBegin++] = pUnsortArray[nIndex1++];
            }
            else
            {
                pSortArray[nBegin++] = pUnsortArray[nIndex2++];
            }
        }
        else if (nIndex1 <= nMid)
        {
            pSortArray[nBegin++] = pUnsortArray[nIndex1++];
        }
        else if (nIndex2 <= nRight)
        {
            pSortArray[nBegin++] = pUnsortArray[nIndex2++];
        }
    }
    //排序完修改原數組
    for (int i = nLeft; i <= nRight; i++)
    { 
        pUnsortArray[i] = pSortArray[i];
    }
}

void Merge(int* pUnsortArray, int nLeft, int nRight, int* pSortArray)
{
    if (nLeft >= nRight)
    {
        return;
    }
    int nMid = (nLeft + nRight) / 2;
    Merge(pUnsortArray, nLeft, nMid, pSortArray);
    Merge(pUnsortArray, nMid + 1, nRight, pSortArray);
    Sort(pUnsortArray, nLeft, nMid, nRight, pSortArray);
}


/*
 * @name   MergeSortRecursion
 * @brief  歸併排序遞歸實現
 * @param  [in] int * array 待排序數組
 * @param  [in] int nLength 數組長度
 * @return void
 */
 void MergeSortRecursion(int* array, int nLength)
{
    if (NULL == array || nLength <= 1)
    {
        return;
    }
    int* pSortArray = new int[nLength];
    Merge(array, 0, nLength - 1, pSortArray);
    delete[] pSortArray;
}


/*
 * @name   MergeSortUnrecursion
 * @brief  歸併排序非遞歸實現
 * @param  [in] int * array 待排序數組
 * @param  [in] int nLength 數組長度
 * @return void
 */
 void MergeSortUnrecursion(int* array, int nLength)
{
    if (NULL == array || nLength <= 1)
    {
        return;
    }
    int* pSortArray = new int[nLength];
    int nSize = 1;//分出的最小組    
    while (nSize <= nLength)
    {
        int nBegin = 0;
        int nMid = 0;
        int nEnd = 0;
        while (nEnd < nLength - 1)
        {            
            nMid = nBegin + nSize - 1;
            nEnd = nMid + nSize;
            if (nEnd >= nLength)
            {
                nEnd = nLength - 1;
            }
            Sort(array, nBegin, nMid, nEnd, pSortArray);
            nBegin = nEnd + 1;
        }
        nSize *= 2;
    }
    delete[] pSortArray;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int a[100] = { };
    for (int i = 0; i < 100; i++)
    {
        a[i] = 50 - i;
    }
    int nLength = sizeof(a) / sizeof(a[0]);
    cout << "排序前:" << endl;
    for (int i = 0; i < 100; i++)
    {
        cout << a[i] << "  ";
    }
    cout << endl;
    cout << "come here" << endl;
    MergeSortUnrecursion(a, nLength);

    cout << "排序後:" << endl;
    for (int i = 0; i < nLength; i++)
    {
        cout << a[i] << "  ";
    }
    cout << endl;
    system("pause");
    return 0;
}

運行結果:

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