(本博客旨在個人總結回顧)
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;
}
運行結果: