歸併排序—演算法導論
阿新 • • 發佈:2018-12-31
#include<iostream> #include<math.h> using namespace std; //二路歸併:將兩個有序序列合併為一個有序序列的過程稱為二路歸併 //歸併排序演算法的關鍵是“合併”兩個已排序序列 void merge(int arr[],int begin,int middle,int end){ int n1=middle-begin+1;//n1:子陣列arr[begin,middle]的長度 int n2=end-middle;//n2:子陣列arr[middle+1,tail]的長度 int i,j,k; int *L=(int*)malloc(sizeof(int)*n1);//建立長度為n1的陣列L int *R=(int*)malloc(sizeof(int)*n2);//建立長度為n2的陣列R for(i=0;i<n1;i++)//將子陣列arr[begin,middle]複製到L[0,n1-1] { L[i]=arr[begin+i]; } for(j=0;j<n2;j++)//將子陣列arr[middle+1,tail]複製到R[0,n2-1] { R[j]=arr[middle+1+j]; } i=0;j=0;k=begin; while(i<n1&&j<n2) { if ( L[i] < R[j] )//選取兩個陣列L[]和R[]中較小的複製到arr[] { arr[k++] = L[i++]; } else { arr[k++] = R[j++]; } } while(i<n1) { arr[k++]=L[i++]; } while(j<n2) { arr[k++]=R[j++]; } } void merge_sort(int arr[],int head,int tail){ int middle; if(head<tail)//若head>=tail,則該陣列最多有一個元素,所以已經排好序 { middle=floor((head+tail)/2);//向下取整 merge_sort(arr,head,middle); merge_sort(arr,middle+1,tail); merge(arr,head,middle,tail); } } int main () { int arr[8] = { 5, 2, 4, 7, 1, 3, 2, 6 }; int i = 0; merge_sort ( arr, 0, 7 ); for ( i = 0; i < 8; i++ ) { printf ( "%d ", arr[i]); } return 0; }
時間複雜度:
當n=2^k時,可得
T(n)=2(2T(n/4)+n/2)+n
=4T(n/4)+2n
=4(2T(n/8)+n/4)+2n ……
=2^kT(1)+kn =n+nlog2^n
如果2^k<n<2^k+1,有T(n)≤T(2^k+1),有T(n)=O(nlog2n)