第七章快速排序之“快速插入排序”(練習7.4-5)
阿新 • • 發佈:2019-02-09
O(∩_∩)O~,這個名字乍聽起來比較黃。其實就是先快速排序進行劃分,等劃分小到一定規模比如k時,進行插入排序,因為規模小到一定程度,插入排序的效率更高。我在前面還寫過一個合併插入排序的演算法,思想跟這個相似。
總的時間複雜度為O(nk+nlg(n/k)),這個很好證明:先進行二分,劃分到規模都為K時停止劃分,此時深度為h,則T(n/2^h)=k,則h=lg(n/k),最底層規模為K的葉節點數目為2^lg(n/k)=n/k,每個k內部插入排序,最壞情況為O(k^2),則總的插入排序時間為(n/k)*(k^2)=nk。每一層的劃分耗費為n,一共需劃分lg(n/k)層,耗費為O(nlg(n/k))。則總的時間複雜度是兩者相加共O(nk+nlg(n/k))。
程式碼如下:
#include <string.h> #include <time.h> #define BUFFER_SIZE 10 int Partition(int *a,int p,int r) { int i=0; int j=0; int tmp=0; int x=0; i=p-1; x=a[r]; for(j=p;j<r;j++) { if(a[j]<=x) { i++; tmp=a[i]; a[i]=a[j]; a[j]=tmp; } } tmp=a[i+1]; a[i+1]=a[r]; a[r]=tmp; return i+1; } int RandomPartition(int *a,int p,int r) { int i=0; int tmp=0; srand((unsigned)time(NULL)); i=rand()%(r-p+1)+p; tmp=a[i]; a[i]=a[r]; a[r]=tmp; return Partition(a,p,r); } void InsertionSort(int *a,int p,int r) { int n=r-p+1; int b[n]; int i=0; int j=0; b[0]=a[p]; for(j=p+1;j<=r;j++) { i=j-1; while(i>=0&&a[j]<=b[i]) { b[i+1]=b[i]; i--; } b[i+1]=a[j]; } for(j=p,i=0;j<=r;j++) { a[j]=b[i]; i++; } } void RandomQuickSort(int *a,int p,int r,int k) { int q=0; if(p>=r) { return; } if(r-p+1<k) { InsertionSort(a,p,r); } else { q=RandomPartition(a,p,r); RandomQuickSort(a,p,q-1,k); RandomQuickSort(a,q+1,r,k); } } int main() { int i=0; int j=0; int a[BUFFER_SIZE]; //隨機生成陣列 srand((unsigned)time(NULL)); for(j=0;j<BUFFER_SIZE;j++) { a[j]=rand()%100; } printf("隨機生成的陣列:\n"); for(i=0;i<BUFFER_SIZE;i++) { printf("%d ",a[i]); } printf("\n"); RandomQuickSort(a,0,BUFFER_SIZE-1,1); printf("對陣列進行快速插入排序:\n"); for(i=0;i<BUFFER_SIZE;i++) { printf("%d ",a[i]); } system("pause"); return 0; }