雖然插入排序的時間複雜度為O(n^2),合并排序的時間複雜度為O(nlgn),但是當子問題規模很小時,插入排序的效率要比合并排序高,所以,可以將合并排序和插入排序進行組合,當合并排序的子數組小到一定程度時,不再進行劃分,而是改變演算法,用插入排序演算法對其進行排序。
#include <stdio.h>#include <string.h>#include <time.h>#define BUFFER_SIZE 10int InsertionSort(int *a,int p,int q){int i=0;int j=0;int b[q-p+1];memset(b,0,sizeof(b));b[0]=a[p];for(i=p+1;i<=q;i++){j=i-p-1;while(j>=0&&b[j]>=a[i]){b[j+1]=b[j]; j--;}b[j+1]=a[i];}for(i=p,j=0;i<=q;i++){a[i]=b[j];j++;}}void Merge(int *a,int p,int q,int r){int n1=q-p+1;int n2=r-q;int i=0;int j=0;int k=0;int b[n1+1];int c[n2+1];memset(b,0,sizeof(b));memset(c,0,sizeof(c));b[n1]=BUFFER_SIZE;//設定哨兵元素,注意不要溢出c[n2]=BUFFER_SIZE;//設定哨兵元素,注意不要溢出for(i=0;i<n1;i++){b[i]=a[p+i];}for(i=0;i<n2;i++){c[i]=a[q+1+i];}for(i=p,j=0,k=0;i<=r;i++){if(b[j]<=c[k]){a[i]=b[j];j++;}else{a[i]=c[k];k++;}}}void MergeAndInsertionSort(int *a,int p,int r,int k){int q=0;if(p>=r){return;}q=(p+r)/2;if((q-p+1)<=k)//子數組長度≤k的時候就不再進行劃分,而是對該子數組進行插入排序 {InsertionSort(a,p,q);}else {MergeAndInsertionSort(a,p,q,k);}if(r-q<=k){InsertionSort(a,q+1,r);}else{MergeAndInsertionSort(a,q+1,r,k);}Merge(a,p,q,r);}void Output(int *a,int len){int i=0;for(i=0;i<len;i++){printf("%d ",a[i]);}printf("\n");}int main(){int i=0;int k=1;int a[BUFFER_SIZE];memset(a,0,sizeof(a));srand((unsigned)time(NULL));for(i=0;i<BUFFER_SIZE;i++){a[i]=rand()%BUFFER_SIZE;}printf("隨機產生的數組:"); Output(a,BUFFER_SIZE);k=rand()%BUFFER_SIZE+1;printf("k=%d\n",k);MergeAndInsertionSort(a,0,BUFFER_SIZE-1,k);printf("排序後的數組:");Output(a,BUFFER_SIZE);system("pause");return 0;}