ok,塵埃落定。期待工作的氣息,越來越濃烈...繼續更新部落格,排序演算法的最後一個——合併排序
合併排序(Merge Sort)是將兩個或多個有序表合併成一個有序表。也稱為二路合併。
合併排序的基本思想是:對於兩個有續表合併初始時,把含有n個節點的待排序序列看做由n個長度為1的有序子表所組成麻將他們一次兩兩合併,得到長度為2的若干有序字表,再對這些字表進行兩兩合併,一直重複道長度為n,排序完成。
資料示例如下:
貼上程式碼:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define ARRAYLEN 11 4 //生成隨機數 5 int CreateData(int a[],int n,int min,int max){ 6 int i,j,flag; 7 8 srand(time(NULL)); 9 10 if((max-min+1) < n) return -1; 11 12 for(i = 0 ; i < n ; i++){ 13 do{ 14 a[i] = rand()%(max-min+1)+min; 15 flag = 0; 16 for(j = 0 ; j < i ; j++){ 17 if(a[i] == a[j]){ 18 flag = 1; 19 break; 20 } 21 } 22 }while(flag); 23 } 24 } 25 26 //對兩個陣列進行合併 27 void MergeStep(int a[],int r[], int s,int m,int e){ 28 int i,j,k; 29 k = s; //s之前的序號都是已排過序的,從s進行下一次合併 30 i = s; //第一個陣列的開始序號 31 j = m+1; //第二個陣列的開始序號 32 while(i<= m && j <= e){ 33 if(a[i] <= a[j]) 34 r[k++] = a[i++]; 35 else 36 r[k++] = a[j++]; 37 } 38 39 while(i <= m) 40 r[k++] = a[i++]; 41 while(j <= e) 42 r[k++] = a[j++]; 43 44 } 45 46 //控制需要合併的兩個陣列的序號 47 void MergePass(int a[],int r[],int n,int len){ 48 int s,e,i; //合併兩個陣列,第一個的起始序號,和結束序號,第二個陣列對應的序號只需要+歩長值len即可 49 s = 0; 50 51 while(s+len < n){ 52 //保證至少有兩個序列進行排序 53 e = s+2*len -1; 54 if(e >= n){ //第二個陣列的結束序號 55 e = n-1; 56 } 57 58 MergeStep(a,r,s,s+len-1,e); 59 60 s = e+1; 61 } 62 63 //當不足兩個序列時退出排序,這時將可能剩餘的一個序列,直接放到r中 64 if(s<n) 65 for(;s<n;s++) 66 r[s] = a[s]; 67 68 } 69 70 71 //每次成倍增加歩長值進行合併 72 void MergeSort(int a[],int n){ 73 int *p; //分配一個和a一樣大小的輔助陣列空間 74 int len = 1; //歩長值 75 int flag = 1; 76 int i; 77 78 if(!(p= (int *)malloc(sizeof(int)*n))){ 79 printf("記憶體分配失敗!\n"); 80 exit(0); 81 } 82 83 while(len < n){ 84 //再歩長值小於總長度的情況下,二路合併相鄰的陣列 85 if(flag) //交替兩個陣列,進行合併 86 MergePass(a,p,n,len); 87 else 88 MergePass(p,a,n,len); 89 90 len *= 2; //歩長值每次增加一倍 91 flag = 1-flag; 92 } 93 94 //當flag=1時,最終排序結果在p中,flag=0時,最終排序結果在a中 95 //因此,當最後flag為1時,將最終結果在放到a中 96 if(flag) 97 for(flag = 0 ; flag < n ; flag++) 98 a[flag] = p[flag]; 99 free(p); 100 } 101 102 103 int main(){ 104 int i,a[ARRAYLEN]; 105 /*for(i=0;i<ARRAYLEN;i++){ 106 a[i] = 0; 107 }*/ 108 109 if(!CreateData(a,ARRAYLEN,1,100)){ 110 printf("生成資料失敗!\n"); 111 return -1; 112 } 113 114 printf("原始資料:\n"); 115 for(i = 0 ; i < ARRAYLEN ; i++){ 116 printf("%d ",a[i]); 117 } 118 119 MergeSort(a,ARRAYLEN); 120 121 printf("\n排序後:\n"); 122 for(i = 0 ; i < ARRAYLEN ; i++){ 123 printf("%d ",a[i]); 124 } 125 printf("\n"); 126 }