希尔(shell)排序算法(c语言实现)

希尔排序是特殊的插入排序,直接插入排序每次插入前的遍历步长为1,而希尔排序是将待排序列分为若干个子序列,对这些子序列分别进行直接插入排序,当每个子序列长度为1时,再进行一次直接插入排序时,结果一定是有序的。

为了弄清希尔排序,我们用一个例子来了解。

我们首先要实现一个希尔排序算法的c语言代码,然后再对其进行讲解。

  1 void ShellSort(SqList *L)
  2 {
  3     int i,j;
  4     int increment = L->length;
  5     do
  6     {
  7         increment = increment/3 + 1;//增量序列
  8         for(i = increment+1; i <= L->length; i++)
  9         {
 10             if(L->r[i] < L->r[i-increment])
 11             {
 12 
 13                 //需将L->r[i]插入有序增量子表
 14 
 15                 L->r[0] = L->r[i];//暂存在L->r[0]
 16 
 17                 for(j = i-increment; j>0 && L->r[0]<L->r[j]; j-=increment)
 18                     L->r[j+increment] = L->[j];//记录后移,查找插入位置
 19 
 20                 L->r[j+increment] = L[0];//插入
 21 
 22             }
 23 
 24         }
 25 
 26     }while(increment > 1);
 27 
 28 }

1.程序开始运行,传入SqList参数值为length=9,r[10]={0, 9, 1, 5, 8, 3, 7, 4, 6, 2},对这个序列进行排序。

下标0123456789
915837462

2.第4行,变量increment就是那个“增量”,我们初始值让它等于待排序的记录数。

3.第5~26行是do循环,终止条件是increment不大于1,即增量为1时就停止循环。

4.第7行为关键,后面再谈。这里执行完后,increment = 9/3 + 1=4.

5.第8~24行是一个for循环,i从4+1=5开始到9结束。

6.第10行,判断L->r[i]与L->r[i-increment]大小,L->r[5]=3小于L->r[i-increment]=L->[1]=9,满足条件,第15行,将L->[5]=3暂存入L->[0]。第17,18行循环将L->[1]=9赋给L->[5],由于循环的增量是j-increment,其实它就循环了一次,此时j=3。第20行,将L->[0]=3赋给L->r[j+increment]=L->[1]=3.即,这段代码就是将第5位的3和第1位的9交换位置。

下标0123456789
3915837462

                                 increment=4     |——9>3,交换——|

7.循环继续,i=6,L->[6]=7>L->r[i-increment]=L->[2]=1,因此不交换两者数据。

下标0123456789
3315897462

                                 increment=4           |——1<7,不交换——|

8.循环继续,i=7,L->[7]=4<L->r[i-increment]=L->[3]=5,交换两者数据。

下标0123456789
4315897462

                                 increment=4                     |——1<7,交换——|

9.循环继续,i=8,L->[8]=6<L->r[i-increment]=L->[4]=8,交换两者数据。

下标0123456789
6314897562

                                 increment=4                            |——1<7,交换——|

10.循环继续,i=9,L->[9]=2<L->r[i-increment]=L->[5]=9,交换两者数据。注意,第17,18行是循环,此时要比较L->[5]与L->[1]比较大小,因为2<3,所以L->[5]与L->[1]进行数据交换。

下标0123456789
2314697582

                                 increment=4                                    |——1<7,交换——|

                                                          |——3>2,交换——|

        最终,第一轮循环结束,此时increment=4,再继续完成下一轮的do循环,得到increment=4/3 + 1=2,在指向上述操作,increment不断减小,直到不大于1,结束循环,这是排序完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值