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


先贴上代码

 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一直指在数组的最后位置)

--------------------------------------------------------------------------------------------------

对于希尔排序的时间复杂度:

希尔算法的时间复杂度与gap的值选取有关 

在之前的插入排序算法中已经描述过:对于两个需要交换元素,它们相距越远,需要交换的次数就越多,于是衍生出了希尔算法,希望解决这个问题。

但是在希尔算法中有两个不确定因素,①原始数组的元素个数和每个元素的大小是不确定的 ②gap值的选取是不确定的

理论上每个确定数组都应该有一个最优的gap值选取使得希尔排序的时间复杂度为最小的O(NlogN),对于确定的数组我们也很容易选择每一次循环的gap使得分组排序无效,希尔排序退化成插入排序

这时的时间复杂度为O(N^2)

所以希尔排序的时间复杂度在O(NlogN) 和O(N^2)之间

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM