希尔排序算法代码实现以及思路

妖精的绣舞 提交于 2019-12-01 18:38:05

先贴上代码

 1 #include<stdio.h>
 2 #define N 12
 3 //length统计数组的长度 返回最后元素的下标 
 4 int length(int a [N]){
 5     for(int i = 0;i<=N;i++){
 6         if(a[i]==0) return i-1;
 7         
 8     }    
 9 } 
10 //打印输出数组元素
11 void show(int a[N]){
12     for(int i= 0;i<N;i++){
13         if(a[i]!=0) printf("%4d",a[i]);
14         
15     }    
16 }  
17  //希尔排序  (插入排序升级版) 
18 void shellsort(int a [N]){
19     int gap = length(a)/2 ; 
20     do{
21     int temp=0;
22     for(int i = gap;i<=length(a);i++){
23         for(int j = i;j>=gap;j-=gap){
24             if(a[j-gap]>a[j]){ 
25             temp = a[j-gap] ; 
26               a[j-gap]=a[j]  ;    
27               a[j]=temp;}                   
28         }    
29     } printf("%d\n",gap);    //打印输出每次循环时gap的数值  输出值依次为为4 2 1  
30     gap/=2;    
31 }while(gap!=0); //这里可以使用for循环也可以使用do while循环 
32 }
33 int main(void){
34     int a [N] ={2,3,467,1,22,3,5,34,4,7} ; //手动生成数组a 
35     printf("%d\n",length(a));
36     shellsort(a);
37     show(a);  //输出 1   2   3   3   4   5   7  22  34 467  结果正确 
38     
39     return 0 ;
40 } 

简单希尔排序算法需要注意的三个关键点在于gap值的选择,以及数组下标i,j和gap的位置关系,要保证程序在gap==1时算法退化成插入排序

以一个简单的数组 7 6 3 2 4  1为例循环开始时,gap简写为g,以括号表示g,i,j所在数字的位置,初始gap=3,数组下标初始值为0,用[]表示需要交换数值的两个元素,需要注意的是gap处在最外层循环,当i的循环结束时,gap的值才会改变

[7](j-g) 6 3 [2](g,i,j) 4 1 -->2 [6](j-gap) 3 7(g)  [4](i,j) 1 -->2  4 [3](i,j) 7(g) 6 [1](i,j)   //从这里第一次i循环结束,gap/2 =1 退化为简单的插入排序  -->[2](j-g) [4](g,i,j) 1 7 6 3 -->2 [4](g) [1](i) 7 6 3 --> [2](i-g) [1](g,i,j) 4 7 6 3 --> 1 2 4 7 6 3  依此类推-------->>> 1 2 4 6 7 3 ---->> 1 2 3  6 7 4 --> 1 2  3 4 6 7 (这三次迭代执行的都是j循环 i一直指在数组的最后位置)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!