【数据结构之排序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

数据结构基础系列(9):排序

-
  • 1970年01月01日 08:00

数据结构实验之排序六:希尔排序 【OJ--3403】

题目描述 我们已经学习了各种排序方法,知道在不同的情况下要选择不同的排序算法,以期达到最好的排序效率;对于待排序数据来说,若数据基本有序且记录较少时,直接插入排序的效率是非常好的,希尔排序就是针...
  • zhang_di233
  • zhang_di233
  • 2015-12-23 19:05:32
  • 1123

数据结构系列之希尔排序详解

基于插入排序的希尔排序Java实现
  • fengyinchao
  • fengyinchao
  • 2015-05-27 09:25:47
  • 2071

数据结构之排序:希尔排序

直接插入排序算法简单,在n值较小时,效率比较高;当n值比较大师,如果待排序序列是按关键字值基本有序,效率依然很高,骑士剑效率可以提高到O(n)O(n)。希尔排序正式从这两点出发对直接插入排序的改进方法...
  • u011080472
  • u011080472
  • 2016-05-02 16:17:03
  • 643

数据结构之直接插入排序、折半插入排序、希尔排序算法

直接插入排序: 我们的记录本身就是基本有序的,我们只需要少量的插入操作,就可以完成整个记录集的排序工作,此时直接插入很高效。还有就是记录数比较少时,直接插入的优势也比较明显。 void InsertS...
  • gotowu
  • gotowu
  • 2015-10-23 16:29:04
  • 3342

【数据结构和算法12】希尔排序

上一章我们学习了冒泡排序、选择排序和插入排序三种基础排序算法,这三种排序算法比较简单,时间复杂度均为O(N2),效率不高。这节我们讨论一个高级排序算法:希尔排序。希尔排序是基于插入排序的,插入排序有个...
  • eson_15
  • eson_15
  • 2016-04-16 16:31:43
  • 3285

数据结构 - 希尔排序(Shell's Sort) 详解 及 代码(C++)

数据结构 - 希尔排序(Shell's Sort) 详解 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy/article/details/2...
  • u012515223
  • u012515223
  • 2014-04-23 14:37:12
  • 2835

数据结构之希尔排序(C语言)

#include #include #include #define SIZE 10 void ShellSort(int *a,int len) { int i,j,h; int r,te...
  • cghver
  • cghver
  • 2012-04-05 15:38:05
  • 1795

数据结构与算法——插入类排序(直接插入排序,希尔排序)

一、直接插入排序 对于一个有序的序列,不断将后面的元素插入前面的有序序列,保持序列继续有序。 对于直接插入排序的思路:将要排序的元素保存,然后逐个和其前面的元素进行比较,如果前面的元素比其大,则将...
  • a879365197
  • a879365197
  • 2015-07-13 10:34:53
  • 654

数据结构 C语言实现希尔排序

一、希尔排序简介 先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行...
  • u010889616
  • u010889616
  • 2015-08-19 22:25:10
  • 839
收藏助手
不良信息举报
您举报文章:【数据结构之排序3】希尔排序
举报原因:
原因补充:

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