1. 程式人生 > >演算法設計與分析——歸併排序

演算法設計與分析——歸併排序

演算法思想

虛擬碼

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;
}