9.6.3 希尔排序算法

        好了,为了能够真正弄明白希尔排序的算法,我们还是老办法——模拟计算机在执行算法时的步骤还研究算法到底是如何进行排序的。
        希尔排序算法代码如下。

void ShellSort(SqList *L)
{int i,j;int increment=L->length;do{increment=increment/3+1;            /* 增量序列 */for(i=increment+1;i<=L->length;i++){if (L->r[i]<L->r[i-increment])    /* 需将L->r[i]插入有序增量子表 */ { L->r[0]=L->r[i];             /* 暂存在L->r[0] */for(j=i-increment;j>0 && L->r[0]<L->r[j];j-=increment)L->r[j+increment]=L->r[j]; /* 记录后移,查找插入位置 */L->r[j+increment]=L->r[0]; /* 插入 */}}}while(increment>1);
}

1) 程序开始运行,此时我们传入的SqList参数的值为length=9,r[10]={0,9,1,5,8,3,7,4,6,2}。这就是我们需要等待排序的序列,如图9-6-4所示。

2) 第4行,变量increment就是那个“增量”,我们初始值让它等于待排序的记录数。
3) 第5~19行是一个do循环,它提终止条件是increment不大于1时。其实也就是增量为1时就停止循环了。
4) 第7行,这一句很关键,但也是难以理解的地方,我们后面还要谈到它,先放一放。这里执行完成后,increment=9/3+1=4。
5) 第8~17行是一for循环,i从4+1=5开始到9结束。
6) 第10行,判断L.r[i]与L.r[i-increment]大小,L.r[5]=3<L.r[i-increment]=L.r[1]=9,满足条件,第12行,将L.r[5]=3暂存入L.r[0]。第13~14行的循环只是为了将L.r[1]=9的值赋给L.r[5],由于循环的增量是j-=increment,其实它就循环了一次,此时j=-3。第15行,再将L.r[0]=3赋值给L.r[j+increment]=L.r[-3+4]=L.r[1]=3。如图9-6-5,事实上,这一段代码就干了一件事,就是将第5位的3和第1位的9交换了位置。

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

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

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

10) 循环继续,i=9,L.r[9]=2<L.r[i-increment]=L.r[5]=9,交换两者数据。注意,第13~14行是循环,此时还要继续比较L.r[5]与L.r[1]的大小,因为2<3,所以还要交换L.r[5]与L.r[1]的数据,如图9-6-9。

最终第一轮循环后,数组的排序结果为图9-6-10所示。细心的同学会发现,我们的数字1、2等小数字已经在前两位,而8、9等大数字已经在后两位,也就是说,通过这样的排序,我们已经让整个序列基本有序了。这其实就是希尔排序的精华所在,它将关键字较小的记录,不是一步一步地往前挪动,而是跳跃式地往前移,从而使得每次完成一轮循环后,整个序列就朝着有序坚实地迈进一步。

11) 我们继续,在完成一轮do循环后,此时由于increment=4>1因此我们需要继续do循环。第7行得到increment=4/3+1=2。第8~17行for循环,i从2+1=3开始到9结束。当i=3、4时,不用交换,当i=5时,需要交换数据,如图9-6-11

12) 此后,i=6、7、8、9均不用交换。如图9-6-12

13) 再次完成一轮do循环,increment=2>1,再次do循环,第7行得到increment=2/3+1=1。此时这就是最后一轮do循环了。尽管第8~17行for循环,i从1+1=2开始到9结束,但由于当前序列已经基本有序,可交换数据的情况大为减少,效率其实很高。如图9-6-13,图中箭头连线为需要交换的关键字。

最终完成排序过程,如图9-6-14。

9.6.4 希尔排序复杂度分析
        通过这段代码的剖析,相信大家有些明白,希尔排序的关键并不是随便的分组后各自排序,而是将相隔某个“增量”的记录组成一个子序列,实现跳跃式的移动,使得排序的效率提高。
        这里“增量”的选取就非常关键了。我们在代码中第7行,是用increment=increment/3+1;的方式选取增量的,可究竟应该选取什么样的增量才是最好,目前还是一个数学难题,迄今为止还没有人找到一种最好的增量序列。不过大量的研究表明,当增量序列为dlta[k]=2t-k+1-1(0≤k≤t≤⌊log2(n+1)⌋)时,可以获得不错的效率,其时间复杂度为O(n3/2),要好于直接排序的O(n2)。需要注意的是,增量序列的最后一个增量值必须等于1才行。另外由于记录是跳跃式的移动,希尔排序并不是一种稳定的排序算法。
        不管怎么说,希尔排序算法的发明,使得我们终于突破了慢速排序的时代(超越了时间复杂度为O(n2)),之后,相应的更为高效的排序算法也就相继出现了。

出处:http://www.cnblogs.com/cj723/archive/2011/04/20/2021648.html

《大话数据结构》第9章 排序 9.6 希尔排序(下)相关推荐

  1. 大话数据结构 第七章 图(二) 最小生成树、最短路径、拓扑排序、关键路径算法

    大话数据结构 第七章 图(二) 最小生成树.最短路径.拓扑排序.关键路径算法 最小生成树 定义 Prim算法 Kruskal算法 最短路径 Dijkstra算法 Floyd算法 拓扑排序 AOV网 拓 ...

  2. 《大话数据结构》样章试读

    <大话数据结构>样章试读 各位童鞋,<大话数据结构>从写作到出版,虽然经历了一些坎坷,但终于还是在今天正式在一些网店发售了.现在提供两章的完整版试读PDF文件,希望能给您有所 ...

  3. 数据结构排序法之希尔排序法(Shell Sort)

    希尔排序,也叫递减增量排序,是插入排序的一种更高效的改进版本.希尔排序是不稳定的排序算法. 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 1.插入排序在对几乎已经排好序的数据操作时,效率高, ...

  4. 【数据结构笔记33】C实现:希尔排序、增量序列

    本次笔记内容: 9.2 希尔排序 文章目录 希尔排序 希尔排序方法 希尔排序实现 改进:更多增量序列 希尔排序 希尔排序方法 由Donald Shell提出,应用了插入排序的简单,但是又克服了插入排序 ...

  5. 我的Java开发学习之旅------gt;Java经典排序算法之希尔排序

    一.希尔排序(Shell Sort) 希尔排序(Shell Sort)是一种插入排序算法,因D.L.Shell于1959年提出而得名. Shell排序又称作缩小增量排序. 二.希尔排序的基本思想 希尔 ...

  6. 我的Java开发学习之旅------Java经典排序算法之希尔排序

    一.希尔排序(Shell Sort) 希尔排序(Shell Sort)是一种插入排序算法,因D.L.Shell于1959年提出而得名. Shell排序又称作缩小增量排序. 二.希尔排序的基本思想 希尔 ...

  7. 十大经典排序算法之希尔排序及其优化

    一.希尔排序 1.概念 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进. 希尔排序又称缩小增量排序,因 DL.Shell 于 1959 年提出而得名. 它通过比较相距 ...

  8. JAVA排序算法之希尔排序

    基本介绍 希尔排序是希尔(Donald Shell)于 1959 年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序. 希尔排序法基本思 ...

  9. [算法]-排序算法之希尔排序

    希尔排序算法思想 希尔排序的实质就是分组插入排序,该方法又称缩小增量排序. 基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个"增量"的元素组成的)分别进行直接插入排序 ...

最新文章

  1. 借助深度卷积神经网络对图片 GIF 视频进行超分辨率放大(即放大与降噪) 以及 对视频进行 插帧(即补帧).
  2. mysql数据库应用与开发姜桂洪 课后答案_一站式打卡“云原生”时代的高效开发...
  3. oracle查询之null值转化
  4. 【干货】移动APP安全测试要点解析
  5. Paxos一致性协议
  6. 北航计算机网络 传输层实验,北航研究生计算机网络实验_实验七 传输层实验
  7. python中plot是什么意思_python中的plot函数是什么?
  8. LuaForUnity8:uLua简介
  9. 利用74HC138译码器实现数码管显示
  10. 手写数字识别mnist
  11. 单机游戏mysql启动不了_魔域单机版MySQL数据库启动失败解决办法
  12. php体检管理系统,学生健康体检信息管理系统
  13. ps 计算机 性能设置,Photoshop 中的性能首选项
  14. 使用OBS屏幕录制时色彩错误问题解决方案
  15. git报错 git libpng warning: iCCP以及fatal: Authentication failed for ‘https://git.weixin.qq.com‘
  16. android mma
  17. python怎么爬取电影海报_Python 爬取猫眼数据分析《无名之辈》为何能逆袭成黑马?...
  18. 忠仕商务通修改对话界面内容
  19. oracle sql 字段值行 连乘,如何使用Oracle数据库将矩阵与其转置相乘,并使用utl_nla...
  20. idea中没有 program arguments 选项

热门文章

  1. jvm性能调优实战 - 42JVM性能优化思路Review
  2. 深入理解分布式技术 - 负载均衡实现之一致性哈希算法
  3. 并发编程-10线程安全策略之不可变对象
  4. 电脑快捷键横屏变竖屏,电脑显示器竖屏横屏来回切换怎么设置
  5. python模块的函数_Python模块及函数的使用
  6. 数据结构与算法笔记(六)—— 冒泡排序
  7. python是什么学了有什么用处_学python有什么用途 就业方向有哪些
  8. 索爱麦克风免驱动的语音录入测试
  9. ROS学习:创建机器人的urdf
  10. 从S3获取数据在html表示,AWS Lambda从DynamoDB加载内容,以S3格式显示在HTML中(示例代码)...