1. 程式人生 > >歸併排序時間複雜度----主定理

歸併排序時間複雜度----主定理

http://blog.csdn.net/touch_2011/article/details/6785881

1、序言

2、歸併排序

          2.1 引出

           歸併排序又是另一類排序演算法,它是一種基於“分治”策略的一種演算法。歸併排序演算法是典型的分治演算法,對於規模較大的問題,可以分解成若干容易求解的簡單的問題,最後把解合併構成初始問題的解。詳細的排序過程可以參考《資料結構》或者《演算法導論》。

          2.2 程式碼

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define INFINITE 1000
  4. //對兩個序列進行合併,陣列從mid分開
  5. //對a[start...mid]和a[start+1...end]進行合併
  6. void merge(int *a,int start,int mid,int end)  
  7. {  
  8.     int i,j,k;  
  9.     //申請輔助陣列
  10.     int *array1=(int *)malloc(sizeof(int)*(mid-start+2));  
  11.     int *array2=(int *)malloc(sizeof(int)*(end-mid+1));  
  12.     //把a從mid分開分別賦值給陣列
  13.     for(i=0;i<mid-start+1;i++)  
  14.         *(array1+i)=a[start+i];  
  15.     *(array1+i)=INFINITE;//作為哨兵
  16.     for(i=0;i<end-mid;i++)  
  17.         *(array2+i)=a[i+mid+1];  
  18.     *(array2+i)=INFINITE;  
  19.     //有序的歸併到陣列a中
  20.     i=j=0;  
  21.     for(k=start;k<=end;k++){  
  22.         if(*(array1+i) > *(array2+j)){  
  23.             a[k]=*(array2+j);  
  24.             j++;  
  25.         }  
  26.         else{  
  27.             a[k]=*(array1+i);  
  28.             i++;  
  29.         }  
  30.     }  
  31.     free(array1);  
  32.     free(array2);  
  33. }  
  34. //歸併排序
  35. void mergeSort(int *a,int start,int end)  
  36. {  
  37.     int mid=(start+end)/2;  
  38.     if(start<end){  
  39.         //分解
  40.         mergeSort(a,start,mid);  
  41.         mergeSort(a,mid+1,end);  
  42.         //合併
  43.         merge(a,start,mid,end);  
  44.     }  
  45. }  
  46. void main()  
  47. {  
  48.     int i;  
  49.     int a[7]={0,3,5,8,9,1,2};//不考慮a[0]
  50.     mergeSort(a,1,6);  
  51.     for(i=1;i<=6;i++)  
  52.         printf("%-4d",a[i]);  
  53.     printf("\n");  
  54. }  

          2.3 效率分析

可以說合並排序是比較複雜的排序,特別是對於不瞭解分治法基本思想的同學來說可能難以理解。總時間=分解時間+解決問題時間+合併時間。分解時間就是把一個待排序序列分解成兩序列,時間為一常數,時間複雜度o(1).解決問題時間是兩個遞迴式,把一個規模為n的問題分成兩個規模分別為n/2的子問題,時間為2T(n/2).合併時間複雜度為o(n)。總時間T(n)=2T(n/2)+o(n).這個遞迴式可以用遞迴樹來解,其解是o(nlogn).此外在最壞、最佳、平均情況下歸併排序時間複雜度均為o(nlogn).從合併過程中可以看出合併排序穩定。 

用遞迴樹的方法解遞迴式T(n)=2T(n/2)+o(n):假設解決最後的子問題用時為常數c,則對於n個待排序記錄來說整個問題的規模為cn。

從這個遞迴樹可以看出,第一層時間代價為cn,第二層時間代價為cn/2+cn/2=cn.....每一層代價都是cn,總共有logn+1層。所以總的時間代價為cn*(logn+1).時間複雜度是o(nlogn).

3、附錄

      參考書籍:  《演算法導論》