7种排序

View Code
  1 /*---------------------------
  2 
  3     程序功能:比较七种排序算法的时间消耗
  4 
  5     七种算法:1.冒泡排序、2.直接插入排序、3.简单选择排序、4.希尔排序、5.堆排序、6.归并排序、7.快速排序。
  6 
  7     统一规约:1,排序为从小到大 升序排序
  8               2,Max  表示排序数组的大小
  9               3,rt   记录前一次运行算法的时间,求差的结果为当前排序时间
 10               4,a[] 为排序数组, a2[] 为恢复数组,每次一个排序结束后由a2[]进行恢复
 11               5,char_len 字符串长度
 12               6,save[] 用在归并事的保存数据
 13               7,Distance 设置快排的比较间隔,小于这个值就会进行插入排序。
 14     
 15 
 16  --------------------------- */
 17 #include<iostream>
 18 //#include<stdio.h>
 19 #include<ctime>
 20 #include<cstdlib>
 21 #include<cmath>
 22 #include<algorithm>
 23 
 24 #define Max 1000000
 25 #define char_len 100
 26 #define Distance 10
 27 
 28 
 29 int a[Max]={0};
 30 int a2[Max]={0};
 31 int save[Max];
 32 
 33 double rt=0.0;
 34 
 35 //计算排序时间函数 用到了 函数指针, 可以调用到 随意函数 来计算排序时间
 36 void printTime( void (*sort )(int a[Max] ) , char name[char_len] ){
 37     clock_t   tick; 
 38     double t;
 39 
 40     //实际排序
 41     sort(a);
 42     tick=clock(); 
 43     //算排序总时间
 44     t=(double)tick/CLK_TCK; 
 45     
 46     printf( "Total time used of  %s  is:  %lf   second\n\n ", name , t-rt); 
 47     rt=t;
 48 }    
 49 
 50 //初始化数组 +  随机函数
 51 void init_array(){
 52     int i=0;
 53     srand((unsigned)time(NULL)); /*随机种子*/ 
 54 
 55     for(i = 1 ; i<Max; i++){
 56         a2[i]=a[i]=rand()*i; 
 57 
 58     // if( i%100==0)
 59     //        printf("\n");
 60     //    printf("%d ",a[i]);
 61     }
 62 }
 63 
 64 //初始化数组 + 将用a2[] 来恢复 a [] 的值 ,恢复到 开始状态
 65 void init_array2(){
 66     int i=0;
 67     for(i = 1 ; i<Max; i++){
 68         a[i]=a2[i]; 
 69     }
 70 }
 71 //打印数组
 72 void print_array(){
 73     int i;
 74     for( i=0; i<Max; i++){
 75         if( i%10==0)
 76             printf("\n");
 77         printf("%d ",a[i]);
 78     }
 79 }
 80 
 81 
 82 
 83 
 84 /*
 85     第一个算法 : 冒泡排序---------------------------------------------------------------------------
 86 
 87   */
 88 //冒泡 a[]
 89 void bubble_sort( int a[]){
 90     int i,j,k;
 91     
 92     for(i=Max ; i>0 ; i--){
 93         for( j=1; j<i-1;j++){
 94             if( a[j]>a[j+1] ){
 95                 k=a[j];
 96                 a[j]=a[j+1];
 97                 a[j+1]=k;
 98             }
 99         }
100     }
101 //    print_array();
102 }
103 
104 
105 
106 /*
107     第二个算法 : 直接插入排序---------------------------------------------------------------------------
108 
109   */
110 
111 
112 //插入排序对 a 中 从 left ---> right 的数据排序, 如此设计可提供快排和归并调用
113 void insertionsort(int a[], int left, int  right){
114     int i , j , k ;
115 
116     for( i=left+1; i<=right; i++){
117         k= a[i];
118         for( j = i-1; j>0 ; j--){
119             if( a[j]> k ){
120                 a[j+1]=a[j];
121             }else{
122             //    a[j+1]=k;
123                 break;
124             }
125         }
126         a[j+1]=k;
127     }
128 }
129 
130 //插入排序接口
131 void insert_sort( int a[]){
132 
133     insertionsort(a , 1, Max-1 );
134 
135 //    print_array();
136 
137 }
138 
139 
140 
141 
142 
143 /*
144     第三个算法 : 简单选择排序---------------------------------------------------------------------------
145 
146   */
147 
148 
149 //查找最值的 递归函数,  对 begin --- > end 中选择最小值的 下表
150 int SelectMin( int begin, int end){
151     int c, b ;
152     int center= (begin+end)/2;
153 
154     if( begin<end){
155         c=SelectMin(begin,center);
156         b= SelectMin(center+1, end);
157         return a[c] < a[b] ? c : b ;
158     }else{
159         return begin;
160     }
161 
162 
163 }
164 //选择排序主函数, 对 a[] 排序。 
165 void select_sort( int a[]){
166     int i, j, k,min;
167     for( i =1; i<Max; i++){
168     /**/min=0xfffffff;
169         for(j=i;j<Max; j++){
170             if(a[j]<min ){
171                 min=a[j];
172                 k=j;
173             }
174         }
175     //    k = SelectMin( i,Max-1);
176 
177         //将每次选择的最小值和前面的数进行对调,数组前半部分有序
178         if( i!=k ){
179             j=a[i];
180             a[i]=a[k];
181             a[k]=j;
182         }
183     }
184 //    print_array();
185 }
186 
187 
188 /*
189     第四个算法 : 希尔排序---------------------------------------------------------------------------
190 
191   */
192 
193 
194 //希尔排序 a, 对 公差为 dk 的 元素排序。
195 void  shell_insert(int a[], int dk){
196     int i, j , k ;
197     for(i=dk+1 ; i< Max ; i++){
198         k=a[i];
199         for( j= i-dk; j>0 ; j-=dk){
200             if( a[j]> k ){
201                 a[j+dk]=a[j];
202             }else{
203             //    a[j+dk]=k;
204                 break;
205             }
206         }
207         a[j+dk]=k;
208     }
209 }
210 //希尔主函数,排序 a[];
211 void  shell_sort( int a[] ){
212     int k=0;
213 
214     //确定公差数量
215     int kp= (int)(log(Max-1)/log(2));
216     
217     //printf("%d\n",kp);
218     for( k=0; k<=kp; k++){
219         //有人统计 希尔的公差为  2^(kp-k)+1 时,效率最高
220         shell_insert( a,(int)pow(2,kp-k)-1);
221     }
222 //    print_array();
223 }
224 
225 
226 
227 /*
228     第五个算法 : 堆排序 ---------------------------------------------------------------------------
229 
230   */
231 
232 
233 // 堆的调整函数, s 表示 当前调整的位置, length 表示 调整范围: a [] 的 1--->length 位置,
234 void heap_adjust( int a[] ,  int s , int length ){
235     int i  ,k; 
236 
237     k = a[s];
238 
239     //确定a[s]是最大元素;s以后的节点都满足这样的定义;
240     for( i = 2*s ; i<length ; i*=2){
241         
242 
243         //这里用到 i+1 <length , 不是 i<length , 错了很久,终于搞定了
244         if( (i+1)<length &&  a[i]<a[i+1] ) i++;
245 
246         if( a[i] <= k ) break;
247 
248         a[s] = a [ i] ;
249 
250         s = i; 
251     }
252     a[ s] = k; 
253 }
254 
255 //堆排主函数, 对 a[] 排序。
256 void heap_sort( int a[] ){
257     
258     int i, k;
259 
260     //对每个非叶节点进行调整(即有孩子的节点)
261     for( i = (Max-1)/2  ; i>0; i--){
262 
263         heap_adjust( a, i, Max);
264     }
265     //将弹出的最大值放在最后,结果就是从小到大
266     for( i = Max-1 ; i > 1; i--){
267         k=a[1];
268         a[1]=a[i];
269         a[i]=k;
270 
271         heap_adjust(a, 1, i);
272     }
273   //  print_array();
274 }
275 
276 
277 /*    
278 
279     第六个算法 : 归并排序 ---------------------------------------------------------------------------
280 
281   */
282 
283 
284 
285 //合并函数, a 中的 left1 —> right1 , a中的 left2 --> right2 ,进行归并
286 void merge ( int a[],int left1,int right1,int left2 ,int right2){
287  
288 
289     int k=0, i , j , m ;
290     
291     for( i = left1 , j = left2 ; i<= right1 && j <= right2 ; ){
292 
293         //我这里放了一个错误:a[l1]<a[l2] ==== 费了半小时调试
294         if(a[i]<a[j])
295             save[k++]=a[i++];
296         else
297             save[k++]=a[j++];
298     }
299     while(i<=right1)
300         save[k++]=a[i++];
301 
302     while(j<=right2)
303         save[k++]=a[j++];
304     for( m= 0 ; m<k; m++){
305         a[left1++]= save[m];
306     }
307 }
308 
309 // 归并递归函数 , left 和 right ,表示 a[]中的问题规模
310 void  MergeSort(int a[],int left, int right ){
311     
312     int center=(left + right ) /2;
313     if(left < right){
314 
315         MergeSort(a,left,center);
316         MergeSort(a,center+1,right);
317         merge(a,left,center,center+1,right);
318     
319     } 
320 }
321 
322 //归并 ( 符合函数入口 )
323 void merge_sort ( int a[] ){
324 
325     MergeSort( a, 1, Max-1 );
326 //    print_array();
327 
328 }
329 
330 
331 
332 
333 /*
334     第七个算法 : 快速排序---------------------------------------------------------------------------
335 
336   */
337 
338 
339 //交换 a[] 数组下 表 为   h  和 t 的值
340 void swap( int h, int t){
341     int k;
342     k=a[h];
343     a[h]=a[t];
344     a[t]=k;
345 }
346 
347 // 在 a[] 中 选择 一个比较适合的比较值
348  int  median3(int a[],int left,int right ){
349 
350     int center =(left + right)/2;
351 
352     if (a[center]<a[left])
353         swap(left,center);
354     if (a[right]<a[left])
355         swap(left,right);
356     if (a[right]<a[center])
357         swap(center,right);
358 
359     swap(center,right);
360 
361     return a[right];
362  }
363 
364 //快排函数, 对 a[] 中的 left -->right 进行切割分块,递归完成。
365  void quickSort(int a[],int left,int right){
366 
367     if (left+Distance <=right)    {
368 
369          int pivot=median3(a,left,right);
370 
371          int i=left,j=right;
372 
373          for(;;){
374             while (a[++i]<pivot){}
375             while (pivot<a[--j]){}     
376             if (i<j)
377                 swap(i,j);
378             else           
379                 break; 
380          }
381 
382         swap (i,right);
383 
384         quickSort(a,left,i-1);
385         quickSort(a,i+1,right); 
386     }
387     else
388            insertionsort(a,left,right);
389  }
390 
391  //函数接口
392  void quick_sort(int a[]  ){
393     
394      quickSort(a,1,Max-1);
395 
396 //     print_array();
397  }
398 
399 
400 
401 /*
402     主函数---------------------------------------------------------------------------
403 
404   */
405 
406 int main(){
407 
408     init_array(); 
409 /*----------------------------------------------
410     
411     第一段测试代码,建议将Max 调整 10000--100000
412     
413       目的为:对每个算法的运行都有一个比较
414     ----------------------------------------------*/
415     /* 
416 
417     printTime(  &bubble_sort ," 冒泡算法");    
418     init_array2();
419     printTime(  &insert_sort ,"插入算法");
420     init_array2();
421     printTime(  &select_sort ,"选择算法");    
422     init_array2();
423     printTime(  &shell_sort  ,"希尔算法");
424     
425     init_array2();
426     printTime(  &heap_sort   ,"堆算法  ");
427 
428     init_array2();
429     printTime(  &merge_sort  ,"归并算法");
430 
431     init_array2();
432     printTime(  &quick_sort  ,"快排算法");*/
433 
434 /*----------------------------------------------
435     
436     第二段测试代码,建议将Max 调整 100000--10000000(十万 到 一千万, 后三个可以到一亿)
437     
438       目的为:对快速算法来个更刺激的比较
439     ----------------------------------------------*/
440     /* 
441     init_array2();
442     printTime(  &shell_sort  ,"希尔算法");*/
443     init_array2();
444     printTime(  &heap_sort   ,"堆算法  ");
445 
446     init_array2();
447     printTime(  &merge_sort  ,"归并算法");
448 
449     init_array2();
450     printTime(  &quick_sort  ,"快排算法");
451 
452     init_array2();
453     printTime(  &sort  ,"快排算法");
454 
455  
456 /*----------------------------------------------
457     
458     第三段测试代码,建议将Max 调整  10--100。并将每个算法后
459     
460       目的为:表示每个算法都是可以的到真确的排序结果
461     ----------------------------------------------*/
462 /*
463     init_array2();printf("冒泡算法");
464     bubble_sort (a);printf("\n");
465     print_array();
466 
467     init_array2();printf("\n插入算法");
468     insert_sort(a);printf("\n");
469     print_array();
470 
471     init_array2();printf("\n选择算法");
472     select_sort(a);printf("\n");
473     print_array();
474 
475 
476     init_array2();printf("\n希尔算法");
477     shell_sort(a);printf("\n");
478     print_array();
479 
480     init_array2();printf("\n堆算法  ");
481     heap_sort(a);printf("\n");
482     print_array();
483     
484     init_array2();printf("\n归并算法");
485     merge_sort(a);printf("\n");
486     print_array();
487     
488     init_array2();printf("\n快排算法");
489     quick_sort(a);printf("\n");
490     print_array();*/
491 
492 
493     printf("\n");
494 
495 
496     return 0;
497 }
498  

 

posted @ 2012-09-04 21:11  pc....  阅读(120)  评论(0)    收藏  举报