算法设计与分析——归并排序

算法思想

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

猜你喜欢

转载自blog.csdn.net/karin_0/article/details/82791839
今日推荐