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

算法思想

歸併排序的思想是基於分治法的思想之上的,也是有分解、解決、合併這三步。
分解:將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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章