算法思想
归并排序的思想是基于分治法的思想之上的,也是有分解、解决、合并这三步。
分解:将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;
}