所谓有鬼 其实是人们心中有个鬼

让我帮你画个符吧

数据结构 排序2 插入排序

插入排序:该排序是把序列中的值插入一个已经排好的序列中,直到序列的结束。

a.直接插入排序:该排序是对冒泡排序的改进,它比冒泡排序快2倍。一般不用在数据大于1000的场合下使用插入排序,或者重复排序超过200数据项的序列。

详细请见代码:

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. #define NUM 50  
  5.   
  6. //插入排序算法  
  7. /*该算法过程如下: 
  8. 如数组{ 4,3,1 } 
  9. 第一轮循环:4和3比较,4>3,先把4赋值到3的位置,变成{ 4,4,1} 
  10. while循环退出,把3赋值到第一个4的位置,变成{ 3, 4, 1} 
  11.  
  12. 第二轮循环:4和1比较,4>1,4赋值到1的位置,变成{ 3,4,4 } 
  13. 继续while循环,3>1,3赋值到第一4的位置,变成{ 3,3,4 } 
  14. while循环退出,把1赋值到第一个3的位置,变成{ 1,3,4 } 
  15. 自此完成插入排序。 
  16. */  
  17. int InsertSort( int a[], int n )  
  18. {  
  19.     int i, j, t;  
  20.   
  21.     for( i = 1; i < n; i++ )  
  22.     {  
  23.         t = a[i];  
  24.         j = i;  
  25.         while( ( j > 0 ) && ( t < a[j-1] ) )  
  26.         {  
  27.             a[j] = a[j-1];  
  28.             j--;  
  29.         }  
  30.         a[j] = t;  
  31.     }  
  32.     return 1;  
  33. }  
  34.   
  35. int main( void )  
  36. {  
  37.     //int a[NUM] = { 3, 4, 2, 5, 1 };  
  38.     int i;  
  39.       
  40.     int a[NUM];  
  41.   
  42.     for( i = 0; i < NUM; i++ )  
  43.     {  
  44.         a[i] = rand() % NUM;  
  45.     }  
  46.   
  47.     //插入排序  
  48.     InsertSort( a, NUM );  
  49.     for( i = 0; i < NUM; i++ )  
  50.     {  
  51.         printf( "%d \n", a[i] );  
  52.     }  
  53.     return 0;  
  54. }  

b.希尔排序( shell sort ):sheell排序通过将数据分成不同的组,先对每一组排序进行排序,然后再对所有的元素进行一次插入排序,以减少数据交换和移动的次数。平均效率是O( nlogn )。其中分组的大小对算法产生重要影响。现在多用D.E.Knuth分组方法。

Shell排序比冒泡排序快5倍,比插入排序大致快2倍。Shell排序比起QuickSortMergeSort(归并排序),HeapSort慢很多。但是它的实现比较简单,它适合于数据量在5k以下并且速度并不是特并重要的场合。它对于数据量较小的数列重复排序是非常好的。

详细请见代码:

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. #define NUM 50  
  5.   
  6. //希尔排序  
  7. //希尔排序是将数据分成若干组的插入排序  
  8. //其原理可以用三步曲来解释:  
  9. //1.插入排序中如果前面已经排好序,再插入一个新的数据是不是很快呀!  
  10. //2.既然很快,为什么不事先排好序。  
  11. //3.  
  12. //算法实例:如数组{ 2,4,3, 1,3,6, 0,2,8 }  
  13. /*先三分组2,4,3; 1,3,6; 5,2,8; 
  14. 第一轮比较:2,4,3与1,3,6对应位置交换后1,3,3; 5,4,6 
  15. 第二轮比较:首先2,4,6的2和5,2,8的5比较,如果5比2小就会交换位置 
  16. 这时还会和1,3,3中的1比较,如果5比1还小,它们交换位置。同理对于 
  17. 其他位的数据做同样的比较。 
  18. 其最后看到的结果是:每段的所有对应位的数是按顺序排列的, 
  19. 同一段的所有数不一定按顺序排列。 
  20.  
  21. Shell排序最后的分段大小必须为1. 
  22. */  
  23. int Shell2DividSort( int a[], int n )  
  24. {  
  25.     //2分法希尔排序  
  26.     int i, j, t, s;  
  27.   
  28.     for( s = n / 2; s > 0; s /= 2 ) //2分法希尔排序  
  29.     {  
  30.         for( i = s; i < n; i++ )   
  31.         {  
  32.             for( j = i - s; j >= 0; j -= s )  
  33.             {  
  34.                 if( a[j] > a[j+s] ) //相邻的两个段的对应位做比较  
  35.                 {  
  36.                     t = a[j];  
  37.                     a[j] = a[j+s];  
  38.                     a[j+s] = t;  
  39.                 }  
  40.             }  
  41.         }  
  42.     }  
  43.     return 1;  
  44. }  
  45.   
  46. int main( void )  
  47. {  
  48. //  int a[NUM] = { 3, 4, 2, 5, 1 };  
  49.     int i;  
  50.       
  51.     int a[NUM];  
  52.   
  53.     for( i = 0; i < NUM; i++ )  
  54.     {  
  55.         a[i] = rand() % NUM;  
  56.     }  
  57.   
  58.     //2分法希尔排序  
  59.     Shell2DividSort( a, NUM );  
  60.     for( i = 0; i < NUM; i++ )  
  61.     {  
  62.         printf( "%d \n", a[i] );  
  63.     }  
  64.     return 0;  
  65. }  
  

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. #define NUM 100  
  5.   
  6. //希尔排序  
  7. //希尔排序是将数据分成若干组的插入排序  
  8. /* 
  9. 希尔排序原来已经知道,就是把数据分组。 
  10. 然而分成不同大小的组,对数据排序时间有不同影响。 
  11. 如数组( a=2,b=1,c=3,d=1 )这样的数组,如果二分法的话, 
  12. 排完的结果是( a=2, d=1; c=3, b=1 )这样没有什么变化。 
  13. 这样的数据其实并不少见,那怎么尽可能避免,让数据分组最大化 
  14. 的起到调整作用呢?目前公认的方式采用特定数作分组大小。 
  15. 至于怎么推导出来的,暂不作考证! 
  16. */  
  17. int ShellSort( int a[], int n )  
  18. {  
  19.     //特定数组希尔排序  
  20.     int i, j, t;  
  21.     int *s, ss;  
  22.     int size[] = {      // Sedgewick增量  
  23.                     1073643521, 603906049, 268386305, 150958081, 67084289,  
  24.                     37730305, 16764929, 9427969, 4188161, 2354689,  
  25.                     1045505, 587521, 260609, 146305, 64769,  
  26.                     36289, 16001, 8929, 3905, 2161,  
  27.                     929, 505, 209, 109, 41,  
  28.                     19, 5, 1, 0   
  29.                 }; //这个数据有两个特定公式算出来的。  
  30.   
  31.   
  32.     for( s = size; *s > n; s++ )  
  33.     {  
  34.         ;           //找到比分段的值比n还小时,确定其地址位置  
  35.     }  
  36.   
  37.     for( ; *s > 0; s++ ) //特定数组希尔排序  
  38.     {  
  39.         ss = *s;  
  40.         for( i = ss; i < n; i++ )   
  41.         {  
  42.             for( j = i - ss; j >= 0; j -= ss )  
  43.             {  
  44.                 if( a[j] > a[j+ss] ) //相邻的两个段的对应位做比较  
  45.                 {  
  46.                     t = a[j];  
  47.                     a[j] = a[j+ss];  
  48.                     a[j+ss] = t;  
  49.                 }  
  50.             }  
  51.         }  
  52.     }  
  53.     return 1;  
  54. }  
  55.   
  56. int main( void )  
  57. {  
  58. //  int a[NUM] = { 3, 4, 2, 5, 1 };  
  59.     int i;  
  60.       
  61.     int a[NUM];  
  62.   
  63.     for( i = 0; i < NUM; i++ )  
  64.     {  
  65.         a[i] = rand() % NUM;  
  66.     }  
  67.   
  68.     //特定数组希尔排序  
  69.     ShellSort( a, NUM );  
  70.     for( i = 0; i < NUM; i++ )  
  71.     {  
  72.         printf( "%d \n", a[i] );  
  73.     }  
  74.     return 0;  
  75. }  


posted on 2010-08-16 15:01  鬼话符  阅读(176)  评论(0)    收藏  举报

导航