C語言排序(五)——插入排序與歸併排序演算法比較
阿新 • • 發佈:2019-01-04
一.實驗內容:
1、 編寫函式分別實現插入排序和歸併排序演算法
2、 編寫主函式通過呼叫函式實現對待排資料的呼叫
3、 待排資料利用隨機函式迴圈產生10萬個以上的資料
4、 利用求系統時間的函式,分別求出2個排序函式呼叫前和呼叫後的時間,計算出插入排序執行時間和歸併排序的執行時間
5、 演算法的比較:
(1) 相同待排序資料下,插入排序和歸併排序演算法的執行時間比較;
(2) 同一種排序演算法下最好的情況,一般情況,最壞的情況執行時間比較
插入排序:插入即表示將一個新的資料插入到一個有序陣列中,並繼續保持有序。例如有一個長度為N的無序陣列,進行N-1次的插入即能完成排序;第一次,陣列第1個數認為是有序的陣列,將陣列第二個元素插入僅有1個有序的陣列中;第二次,陣列前兩個元素組成有序的陣列,將陣列第三個元素插入由兩個元素構成的有序陣列中......第N-1次,陣列前N-1個元素組成有序的陣列,將陣列的第N個元素插入由N-1個元素構成的有序陣列中,則完成了整個插入排序。
以下面5個無序的資料為例:
65 27 59 64 58 (文中僅細化了第四次插入過程)
第1次插入: 27 65 59 6458
第2次插入: 27 59 65 6458
第3次插入: 27 59 64 6558
第4次插入: 27 58 59 6465
二.演算法分析
三.實驗程式碼
#include<stdio.h> #include<stdlib.h>//數學 #include<time.h>//時間 void insertSort(long int *, long int); //定義插入排序函式 void merge(long int X[], long int Z[], long int s, long int u, long int v); void mergePass(long int X[], long int Y[],long int n, long int t); void mergeSort(long int X[],long int n); void insertSort(long int *array,long int len) { long int i,j,temp; for(i=1;i<len;i++) //從第二個元素開始 { temp=array[i]; //取出代插元素 for(j=i-1;j>=0;j--) //帶插元素依次和前一個比較,將較大數依次後移 { if(array[j]>temp) { array[j+1]=array[j]; }else { break; } } array[j+1] = temp; } } //將有序的X[s..u]和X[u+1..v]歸併為有序的Z[s..v] void merge(long int X[],long int Z[], long int s, long int u, long int v) { long int i, j, q; i = s; j = u + 1; q = s; while( i <= u && j<= v ) { if( X[i] <= X[j] ) Z[q++] = X[i++]; else Z[q++] = X[j++]; } while( i <= u ) //將X中剩餘元素X[i..u]複製到Z Z[q++] = X[i++]; while( j <= v ) //將X中剩餘元素X[j..v]複製到Z Z[q++] = X[j++]; } /* X[0..n-1]表示參加排序的初始序列 * t為某一趟歸併時子序列的長度 * 整型變數i指出當前歸併的兩個子序列中第1個子序列的第1個元素的位置 * Y[0..n-1]表示這一趟歸併後的結果 */ void mergePass(long int X[], long int Y[], long int n,long int t) { int i = 0, j; while( n - i >= 2 * t ) //將相鄰的兩個長度為t的各自有序的子序列合併成一個長度為2t的子序列 { merge(X, Y, i, i + t - 1, i + 2 * t - 1); i = i + 2 * t; } if( n - i > t ) //若最後剩下的元素個數大於一個子序列的長度t時 merge(X, Y, i, i + t - 1, n - 1); else //n-i <= t時,相當於只是把X[i..n-1]序列中的資料賦值給Y[i..n-1] for( j = i ; j < n ; ++j ) Y[j] = X[j]; } void mergeSort(long int X[],long int n) { long int t = 1; long int *Y = (long int *)malloc(sizeof(long int) * n); while( t < n ) { mergePass(X, Y, n, t); t *= 2; mergePass(Y, X, n, t); t *= 2; } free(Y); } void print_array(long int array[],long int n) { long int i; for( i = 0 ; i < n ; ++i ) printf("%d ", array[i]); printf("\n"); } int main() { printf("請輸入要產生的隨機數個數:"); double start, finish; long int a[100005],b[100005],c[100005],d[100005],n,i; scanf("%d",&n); for(i=0;i<n;i++) { a[i]=b[i]=rand()%10000+1; //產生隨機數 //printf("%d ",b[i]); } start=clock();//取開始時間 insertSort(a, n); finish = clock();//取結束時間 printf("採用插入排序的時間:"); printf( "%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000);//以秒為單位顯示之 // for(i=0;i<n;i++) // { // printf("%d ",a[i]); //} start=clock();//取開始時間 mergeSort(b,n); // print_array(b,n); finish = clock();//取結束時間 printf("採用歸併排序的時間:"); printf( "%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000);//以秒為單位顯示之 /* for(i=0; i<n; i++) printf("%d ", a[i]);*/ printf("\n"); printf("%d個數插入排序最好結果用時:",n); start=clock();//取開始時間 for(i=0;i<100000;i++) { c[i]=i; } insertSort(c,i-1); finish = clock();//取結束時間 printf( "%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000); ///////////////////////////////////////// /* for(i=0;i<100;i++) { printf("%d ",c[i]); } printf("\n\n\n\n\n"); */ ////////////////////////////////////////// printf("%d個數插入排序最壞結果用時:",n); start=clock();//取開始時間 for(i=99999;i>=0;i--) { d[i]=99999-i; } insertSort(d,n); finish = clock();//取結束時間 printf( "\n%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000); ///////////////////////////////////////// /* for(i=0;i<100;i++) { printf("%d ",c[i]); } printf("\n\n\n\n\n"); */ ////////////////////////////////////////// printf("%d個數歸併排序最好結果用時:",n); start=clock();//取開始時間 for(i=0;i<n;i++) { c[i]=i; } mergeSort(c,n); finish = clock();//取結束時間 printf( "%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000); printf("%d個數歸併排序最壞結果用時:",n); start=clock();//取開始時間 for(i=n-1;i>=0;i--) { d[i]=99999-i; } mergeSort(d,n); /*for(i=0;i<n;i++) { printf("%d ",d[i]); } */ finish = clock();//取結束時間 printf( "\n%f 毫秒\n",(finish-start)/CLOCKS_PER_SEC*1000); return 0; }
四.實驗結果
五.實驗分析
在隨機陣列中,歸併排序明顯優於插入排序,且數值越大越明顯。有序序列結果不明顯,但仍然歸併排序優於插入排序。