數據結構基礎(5) --歸併排序

歸併排序的基本思想:

    將兩個或兩個以上的有序子序列”歸併”爲一個有序序列:假定待排序表含有n個記錄, 則可以看成是n個有序的子表, 每個子表長度爲1, 然後兩兩歸併, 得到[n/2]個長度爲2或1的有序表,; 再量量歸併, ...., 如此重複, 直到合併成爲一個長度爲n的有序表爲止, 這種排序方法稱爲2-路歸併排序.如圖爲一個2-路歸併排序的一個示例:


  1. /**說明: 
  2.     將有序的記錄序列 initList[left:mid] 和 initList[mid+1:right]歸併爲有序的記錄序列 initList[left:right] 
  3.     initList:  原始的有序序列[分爲兩段] 
  4.     tmpList:     合併過程中需要的中間序列 
  5.     left:       initList最左邊元素的下標 
  6.     mid:        指向第一個有序序列的最後一個元素的下標 
  7.     right:      initList最右邊元素的下標 
  8. */  
  9. template <typename Type>  
  10. int Merge(Type *initList, Type *tmpList, int left, int mid, int right)  
  11. {  
  12.     //先將待歸併的數組複製到tmpList中去  
  13.     std::copy(initList+left, initList+right+1, tmpList+left);  
  14. //    同下:  
  15. //    for (int i = left; i <= right; ++i)  
  16. //    {  
  17. //        tmpList[i] = initList[i];  
  18. //    }  
  19.   
  20.     int s1 = left, s2 = mid+1;  
  21.     int iResult = left;  
  22.     while (s1 <= mid && s2 <= right)  
  23.     {  
  24.         if (tmpList[s1] <= tmpList[s2])  
  25.         {  
  26.             initList[iResult ++] = tmpList[s1 ++];  
  27.         }  
  28.         else  
  29.         {  
  30.             initList[iResult ++] = tmpList[s2 ++];  
  31.         }  
  32.     }  
  33.   
  34.     int *end;  
  35.     if (s1 <= mid)  
  36.         end = std::copy(tmpList+s1, tmpList+mid+1, initList+iResult);  
  37.     if (s2 <= right)  
  38.         end = std::copy(tmpList+s2, tmpList+right+1, initList+iResult);  
  39.     return end - (initList+left);  
  40.   
  41. //    同下:其實這兩個循環只有一個會執行  
  42. //    while (s1 <= mid)  
  43. //    {  
  44. //        initList[iResult ++] = tmpList[s1 ++];  
  45. //    }  
  46. //    while (s2 <= right)  
  47. //    {  
  48. //        initList[iResult ++] = tmpList[s2 ++];  
  49. //    }  
  50. //  
  51. //    return iResult;  
  52. }  
  1. //二路歸併排序-遞歸算法  
  2. template <typename Type>  
  3. void mergeSort(Type *initList, Type *tmpList, int left, int right)  
  4. {  
  5.     if (left >= right)  
  6.         return;  
  7.   
  8.     int mid = (left+right)/2;  
  9.     mergeSort(initList, tmpList, left, mid);    //先將左邊元素排序  
  10.     mergeSort(initList, tmpList, mid+1, right); //後將右邊元素排序  
  11.     Merge(initList, tmpList, left, mid, right); //合併  
  12. }  

可以看出對n個記錄進行歸併排序的時間複雜度爲Ο(nlogn)。即:

    (1)每一趟歸併(合併)的時間複雜度爲 O(n);

    (2)總共需進行[logn]趟。



原文地址:http://blog.csdn.net/zjf280441589/article/details/42366865

發佈了62 篇原創文章 · 獲贊 16 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章