算法思想
歸併排序的思想是基於分治法的思想之上的,也是有分解、解決、合併這三步。
分解:將n個元素的序列分成兩個子序列, 記爲A[ 1 . . .n/2.]and A[ [n/2]+1 . . n ]
解決:將兩個子序列分別遞歸歸併排序
合併:將已有序的兩個子序列合併,得到有序的序列。
僞代碼
MERGE-SORT A[1…n]
1.If n= 1, done.
2.Recursively sort A[ 1 . . .n/2.]and A[ [n/2]+1 . . n ] .
3.“Merge” the 2 sorted lists.
Key subroutine: Merge(有序子列的歸併)
算法複雜度
若將歸併算法的時間複雜度記爲T(n)
c1代價爲1,c2代價爲2T(n/2),c3代價爲n(有序子列的歸併代價爲n,詳情見Merge的代碼實現)
故當n=1時,T(n)=Θ(1);
當n>1時,T(n)=2T(n/2)+Θ(n)
代碼實現
Merge(有序子列的歸併)
void Merge(int *Arr,int *tempArr, int l, int r, int right)
//*Arr待合併序列,*tempArr存放合併後序列
//l,r是待合併序列中子序列1的左、右位置; left,rigt子序列2的左、右位置
{
int left=r+1;
int templ=l;//合併後序列的初始位置
while(l<=r&&left<=right)
{
if(Arr[l]<=Arr[left])
tempArr[templ++]=Arr[l++];
else
tempArr[templ++]=Arr[left++];
}
while(l<=r)
tempArr[templ++]=Arr[l++];
while(left<=right)
tempArr[templ++]=Arr[left++];
for(int k=0;k<templ;k++)//將合併後的序列按順序賦給初始序列*Arr
{
Arr[k]=tempArr[k];
}
}
MergeSort函數
//利用遞歸思想
void MergeSort(int *sourceArr,int *resultArr,int startIndex,int endIndex)
//*sourceArr源序列,*resultArr排序後序列
{
int midIndex;
if(startIndex<endIndex)//序列內有元素
{
midIndex=startIndex+(endIndex-startIndex)/2;//序列的中間位置
MergeSort(sourceArr,resultArr,startIndex,midIndex);
MergeSort(sourceArr,resultArr,midIndex+1,endIndex);
Merge(sourceArr, resultArr, startIndex, midIndex, endIndex);
}
}
主函數
int main()
{
int a[] = {5,2,4,6,1,3};//c++數組中序號從0~5,而長度爲6
int len = sizeof(a)/sizeof(int);//獲取數組長度
int b[len];
int n=len-1;//序列尾序號
MergeSort(a,b,0,n);
for(int k=0;k<len;k++)
{
cout<<a[k]<<" ";
}
cout<<endl;
}