【数据结构之排序3】希尔排序

转载 2013年10月21日 16:07:30

本节介绍第二种插入排序方法:希尔排序。

希尔排序(Shell Sort)是插入排序的一种。因D.L.Shell于1959年提出而得名。


希尔排序基本思想


基本思想:
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-1<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
该方法实质上是一种分组插入方法。


给定实例的shell排序的排序过程


假设待排序文件有10个记录,其关键字分别是:
49,38,65,97,76,13,27,49,55,04。
增量序列的取值依次为:
5,3,1
排序过程如【动画模拟演示】


Shell排序的算法实现


1. 不设监视哨的算法描述

  void ShellPass(SeqList R,int d)
   {//希尔排序中的一趟排序,d为当前增量
     for(i=d+1;i<=n;i++) //将R[d+1..n]分别插入各组当前的有序区
       if(R[i].key<R[i-d].key){
         R[0]=R[i];j=i-d; //R[0]只是暂存单元,不是哨兵
         do {//查找R[i]的插入位置
            R[j+d];=R[j]; //后移记录
            j=j-d; //查找前一记录
         }while(j>0&&R[0].key<R[j].key);
         R[j+d]=R[0]; //插入R[i]到正确的位置上
       } //endif
   } //ShellPass


  void  ShellSort(SeqList R)
   {
    int increment=n; //增量初值,不妨设n>0
    do {
          increment=increment/3+1; //求下一增量
          ShellPass(R,increment); //一趟增量为increment的Shell插入排序
       }while(increment>1)
    } //ShellSort

注意:
当增量d=1时,ShellPass和InsertSort基本一致,只是由于没有哨兵而在内循环中增加了一个循环判定条件"j>0",以防下标越界。



2.设监视哨的shell排序算法

具体算法略。


算法分析



1.增量序列的选择

Shell排序的执行时间依赖于增量序列。
好的增量序列的共同特征:
① 最后一个增量必须为1;
② 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。
有人通过大量的实验,给出了目前较好的结果:当n较大时,比较和移动的次数约在n1.25到1.6n1.25之间。


2.Shell排序的时间性能优于直接插入排序

希尔排序的时间性能优于直接插入排序的原因:
①当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。
②当n值较小时,n和n2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(n2)差别不大。
③在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。
因此,希尔排序在效率上较直接插人排序有较大的改进。


3.稳定性

希尔排序是不稳定的。参见上述实例,该例中两个相同关键字49在排序前后的相对次序发生了变化。


原文地址:http://student.zjzk.cn/course_ware/data_structure/web/main.htm

【数据结构】几种常见的排序算法

一、排序算法的分类     下图是我掌握的一些排序算法,我将他们做了分类,当然,排序算法远不止这些。 本篇博客主要记录插入,选择,以及交换排序的冒泡排序,因为快排和归并算法相对复杂,所以,...
  • pointer_y
  • pointer_y
  • 2016年11月26日 23:06
  • 1393

关于数据结构三种简单的排序总结

大家都知道,对于数据结构有三种简单的排序:冒泡排序,选择排序和插入排序,说他们简单是因为他们在排序的速度相对较慢,而且排序的算法也比较简单,更适用于数据量小的文件排序中。下面我们就分别来分析一下这三种...
  • u014788114
  • u014788114
  • 2015年11月09日 23:37
  • 778

【数据结构排序算法系列】数据结构八大排序算法

排序算法在计算机应用中随处可见,如Windows操作系统的文件管理中会自动对用户创建的文件按照一定的规则排序(这个规则用户可以自定义,默认按照文件名排序)因此熟练掌握各种排序算法是非常重要的,本博客将...
  • htq__
  • htq__
  • 2016年03月25日 22:36
  • 94228

数据结构——外部排序

之前有写过内部排序,这次看到严蔚敏老师的书上还介绍了外部排序,就一起记录一下,以便以后可以看看: 1.外部排序 外部排序是指数据量很大,一下子不能将所有的数据放入内存里面进行排序,只能一部分一部分从硬...
  • rqc112233
  • rqc112233
  • 2015年10月30日 16:43
  • 751

数据结构之排序:直接选择排序

选择排序的主要思想是每一趟从待排序序列中选取一个关键值最小的记录,即第1趟从n个记录中选取关键字值最小的记录,第2趟从剩下的n-1个记录中选取关键字值最小的记录,知道整个序列中的记录都选完为止。由选取...
  • u011080472
  • u011080472
  • 2016年05月02日 17:42
  • 389

重学数据结构系列之——八大排序算法

一、有一种分类 稳定排序:如果线性表中的两个元素 a​i 和 aj​​  满足 i 简单来说就是排序前有两个或多个相等的元素,排序后他们的相对位置不会改变) 不稳定排序:不是上面的情况就是了 ...
  • u012763794
  • u012763794
  • 2016年04月19日 23:11
  • 2276

数据结构与算法-----冒泡排序

冒泡排序 1)算法 A.比较相邻的元素,如果第一个比第二个大就交换它们; B.对每一对相邻的元素都做同样的工作,从开始的第一对到结尾的最后一对。经过这一步,最后的元素是最大值; C.针对所有的...
  • u010193457
  • u010193457
  • 2015年12月02日 16:10
  • 1877

数据结构之排序算法(二)-冒泡排序及改进

冒泡排序算法需要遍历几次数组。每次遍历都要比较连续相邻的元素,如果某一对相邻元素是降序,则互换它们的值,否则,保持不变。由于较小的值像“气泡”一样逐渐浮想顶部,而较大的值沉向底部,所以叫冒泡排序。 ...
  • tuke_tuke
  • tuke_tuke
  • 2015年12月21日 15:10
  • 2060

数据结构与算法--查找与排序(一)

Top 线性查找二分查找冒泡排序插入排序选择排序快速排序归并排序 1 线性查找 1.1 问题 线性查找,又称为顺序查找,是指在所有给定的值中从一端开始逐个检查每个元素是否为要查...
  • opera95
  • opera95
  • 2016年04月22日 08:30
  • 2748

数据结构之排序:冒泡排序

冒泡排序(Bubble Sort)基本思想将待排序的数组看成从上到下排放,把关键字值较小的记录看成“较轻的”气泡,关键字值较大的看成“较重的”石块,较轻的上浮,较重的下沉。所有的气泡和石块都在相应的位...
  • u011080472
  • u011080472
  • 2016年05月02日 16:38
  • 555
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【数据结构之排序3】希尔排序
举报原因:
原因补充:

(最多只允许输入30个字)