經(jīng)典排序算法-歸并排序MergeSort
歸并排序(Merge sort,即合并排序)是建立在歸并操作上的一種有效的
排序算法。該算法是采用
分治法(Divide and Conquer)的一個非常典型的應(yīng)用。其時間復(fù)雜度為O(n)O(最優(yōu))、(nlog n)(最差)。
算法描述
歸并排序具體工作原理如下(假設(shè)序列共有n個元素):
- 將序列每相鄰兩個數(shù)字進(jìn)行歸并操作,形成
個序列,排序后每個序列包含兩個元素 - 將上述序列再次歸并,形成
個序列,每個序列包含四個元素 - 重復(fù)步驟2,直到所有元素排序完畢
其中一次歸并操作的過程如下:
- 申請空間,使其大小為兩個已經(jīng)排序序列之和,該空間用來存放合并后的序列
- 設(shè)定兩個指針,最初位置分別為兩個已經(jīng)排序序列的起始位置
- 比較兩個指針?biāo)赶虻脑?,選擇相對小的元素放入到合并空間,并移動指針到下一位置
- 重復(fù)步驟3直到某一指針達(dá)到序列尾
- 將另一序列剩下的所有元素直接復(fù)制到合并序列尾
#include <iostream>
using namespace std;

//合并排序的合并程序他合并數(shù)組nData中位置為[nP,nM) 和[nM,nR).這個是更接近標(biāo)準(zhǔn)的思路
bool MergeStandard(int nData[], int nP, int nM, int nR)

{
int n1 = nM - nP; //第一個合并數(shù)據(jù)的長度
int n2 = nR - nM; //第二個合并數(shù)據(jù)的長度
int *pnD1 = new int[n1 + 1]; //申請一個保存第一個合并數(shù)據(jù)的空間
int *pnD2 = new int[n2 + 1]; //申請一個保存第二個合并數(shù)據(jù)的空間
for (int i = 0; i < n1; ++i) //復(fù)制第一個數(shù)據(jù)到臨時空間里面

{
pnD1[i] = nData[nP + i];
}
pnD1[n1] = INT_MAX; //將最后一個數(shù)據(jù)設(shè)置為最大值(哨兵)
for (i = 0; i < n2; ++i) //復(fù)制第二個數(shù)據(jù)到臨時空間里面

{
pnD2[i] = nData[nM + i];
}
pnD2[n2] = INT_MAX; //將最后一個數(shù)據(jù)設(shè)置為最大值(哨兵)
n1 = n2 = 0;
while(nP < nR)

{
nData[nP++] = pnD1[n1] < pnD2[n2] ? pnD1[n1++] : pnD2[n2++]; //取出當(dāng)前最小值到指定位置
}
delete []pnD1;
delete []pnD2;
return true;
}

//合并的遞歸調(diào)用,排序[nBegin, nEnd)區(qū)間的內(nèi)容
bool MergeRecursion(int nData[], int nBegin, int nEnd)

{
if (nBegin >= nEnd - 1) //已經(jīng)到最小顆粒了,直接返回

{
return false;
}
int nMid = (nBegin + nEnd) / 2; //計(jì)算出他們的中間位置,便于分治
MergeRecursion(nData, nBegin, nMid); //遞歸調(diào)用,先合并排序好左邊一半
MergeRecursion(nData, nMid, nEnd); //遞歸調(diào)用,后合并排序好右邊一半
// Merge(nData, nBegin, nMid, nEnd); //將已經(jīng)合并排序好的左右數(shù)據(jù)合并,時整個數(shù)據(jù)排序完成
MergeStandard(nData, nBegin, nMid, nEnd);//(用更接近標(biāo)準(zhǔn)的方法合并)
//Output(nData,nEnd);
return true;
}
//合并排序
bool MergeSort(int nData[], int nNum)

{
return MergeRecursion(nData, 0, nNum); //調(diào)用遞歸,完成合并排序
}


/**///////////排序后輸出函數(shù)
int Output(int b[],int length)

{
for (int i=0;i<length;i++)

{
cout<<b[i]<<" ";
}
cout<<endl;
return 1;
}
int main()

{
//int nData[10] = {4,10,3,8,5,0,7,4,0,2}; //創(chuàng)建10個數(shù)據(jù),測試
int size_nData;
cout<<"Enter the numble of nData: size_nData=";
cin>>size_nData;
cout<<endl<<"Enter nData(size_a values):";
int* nData=new int[size_nData];
for (int i=0;i<size_nData;i++)

{
cin>>nData[i];
}

MergeSort(nData, size_nData);
Output(nData, size_nData);
delete []nData;
return 0;
}
posted on 2012-05-11 13:32
代碼之美 閱讀(1538)
評論(0) 編輯 收藏 引用 所屬分類:
經(jīng)典排序算法(C/C++實(shí)現(xiàn))