#排序算法#【5】合并排序
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 }