我们都知道C++排序方法中,有四种常用方法插入排序、希尔排序、交换排序以及选择排序。上一篇文章,我们介绍了插入排序,今天我们介绍另一种排序方法――希尔排序。(本系列文章统一 测试程序)

希尔排序

前面的算法的平均效率都不怎么好,但我们注意到直插排序在关键码基本有序的情况下,效率是最好的,并且,在关键码的数量很少的时候,n和n2的差距也不是那么的明显。基于以上的事实,D.L.Shell在1959年(老古董了)提出了缩小增量排序,基本思想是:取一个间隔(gap),将序列分成若干的子序列,对每个子序列进行直插排序;然后逐渐缩小间隔,重复以上过程,直到间隔为1。在开始的时候,每个子序列里关键码很少,直插的效率很高;随着间隔的缩小,子序列的关键码越来越多,但是在前面的排序基础上,关键码已经基本有序,直插的效率依然很高。

希尔排序的时间复杂度不好估量,gap的选取也没有定论,gap=[gap/2]的程序是最好写的,至于为什么,写写就知道了。template

voidShellSort(T a[],intN,int& KCN,int& RMN)

{

KCN = 0; RMN = 0;

for(intgap = N/2; gap; gap = gap/2)

for(inti = gap; i

{

T temp = a[i]; RMN++;

for(intj = i; j >= gap && ++KCN && temp

{ a[j] = a[j - gap]; RMN++; }

a[j] = temp; RMN++;

}

}

测试结果:Sort ascending N=10000 TimeSpared: 0ms

KCN=120005 KCN/N=12.0005 KCN/N^2=0.00120005 KCN/NlogN=0.903128

RMN=240010 RMN/N=24.001 RMN/N^2=0.0024001 RMN/NlogN=1.80626

Sort randomness N=10000 TimeSpared: 10ms

KCN=258935 KCN/N=25.8935 KCN/N^2=0.00258935 KCN/NlogN=1.94868

RMN=383849 RMN/N=38.3849 RMN/N^2=0.00383849 RMN/NlogN=2.88875

Sort descending N=10000 TimeSpared: 10ms

KCN=172578 KCN/N=17.2578 KCN/N^2=0.00172578 KCN/NlogN=1.29878

RMN=302570 RMN/N=30.257 RMN/N^2=0.0030257 RMN/NlogN=2.27707

注意到这时的测试结果很不准确了,10000个整数的排序已经测试不出什么来了(估计新机器都是0ms,我这里也有个别的时候全是0)。因此,下面用100000个整数的排序重新测试了一次:Sort ascending N=100000 TimeSpared: 140ms

KCN=1500006 KCN/N=15.0001 KCN/N^2=0.000150001KCN/NlogN=0.903094

RMN=3000012 RMN/N=30.0001 RMN/N^2=0.000300001RMN/NlogN=1.80619

Sort randomness N=100000 TimeSpared: 230ms

KCN=4041917 KCN/N=40.4192 KCN/N^2=0.000404192KCN/NlogN=2.43348

RMN=5598883 RMN/N=55.9888 RMN/N^2=0.000559888RMN/NlogN=3.37086

Sort descending N=100000 TimeSpared: 151ms

KCN=2244585 KCN/N=22.4459 KCN/N^2=0.000224459KCN/NlogN=1.35137

RMN=3844572 RMN/N=38.4457 RMN/N^2=0.000384457RMN/NlogN=2.31466

这个结果表明,希尔排序几乎没有最坏情况,无论是正序、逆序、乱序,所用时间都不是很多,附加储存是O(1),的确非常不错。在没搞清楚快速排序、堆排序之前,它的确是个很好的选择,我当年一直用它。

c++语言编程希尔排序法排序,经典四讲贯通C++排序之二 希尔排序相关推荐

  1. Java黑皮书课后题第7章:*7.20(修改选择排序法)在7.11节中,使用了选择排序法对数组排序。改写7.11节程序,重复地在当前数组中找到最大值,然后将这个最大值与该数组中的最后一个数进行交换

    7.20(修改选择排序法)在7.11节中,使用了选择排序法对数组排序.改写7.11节程序,重复地在当前数组中找到最大值,然后将这个最大值与该数组中的最后一个数进行交换 题目 题目描述 破题 代码 运行 ...

  2. c语言排序法{几大经典排序法}【内含详细程序分析过程】(详细易懂版)

    插入排序法(直接插入) int i,j,a[7],temp; \\先设定一个可以含有7个数字的数组(这个7根据需要改变)for(i=1;i<7;i++){temp=a[i]; \\a[i]就是你 ...

  3. 通讯录c语言编程按字母分组,iOS - 通讯录开发,名字按拼音首字母分组排序

    应项目需要,需添加一个自定义的通讯录,所以需要对联系人按名字的首字母进行排序.以下方法已经封装好,复制到项目中直接可以使用. 该方法是使用UILocalizedIndexedCollation来进行本 ...

  4. 用选择排序法对数组中10个整数从大到小排序

    选择排序法:在一组数据中,选出最小(大)的一个数,与第一个位置的数交换,在剩下数中找最小(大)的与第二个位置的数交换,以此类推. 使用一个函数实现: #include<stdio.h> v ...

  5. c语言编程用进退法求搜索区间代码,用c对函数进行优化的问题

    //多维无约束优化软件设计#include #include #include double det=1e-5; //计算精度double det1=1e-3; //梯度判断精度double ak=3 ...

  6. C语言编程用递归法求

    7,用递归法求: (x2!)+(xxx3!)+(5个x相乘5!)+-+((2n-2)个x相乘(2n-2)!)当N为某值是上式为几?(到第n项,n和x的值有键盘输入.) #include<stdi ...

  7. 艾宾浩斯c语言编程,艾宾浩斯记忆法

    1. 初记单词时需要记忆的内容: a) 单词外观, b) 单词的中文释义, c) 单词的记忆法 2. 每个list的具体背诵过程(每个list按12页,每页10个单词计): a) 背完一页(大约5分钟 ...

  8. 最短寻道时间算法c语言,如果北京到上海有千亿条路,寻找最短路径用C语言编程用枚举法没效率,应该用什么算法才能高效解决它?...

    满意答案 l3324147 2013.12.02 采纳率:42%    等级:12 已帮助:6324人 迪杰斯特拉(Dijkstra)算法求图的单源最短路径 template void Dijkstr ...

  9. c语言编程顺序查找法,建立顺序表,实现顺序表的遍历,在顺序表中查找关键字为e的元素(c语言编写)...

    满意答案 qqea12345 推荐于 2017.11.24 采纳率:45%    等级:7 已帮助:1062人 楼主我大二 也刚上数据结构耶 这是我上实验课的时候用链表写的 还没交老师看  功能还差一 ...

最新文章

  1. C语言面试题-这些简单的你能很快的写出来吗?
  2. 对操作系统的五点感受--接口/进程/内存/磁盘管理/系统架构
  3. C指针原理(46)-C应用技巧(1)
  4. Laravel报错Failed opening required ‘bootstrap/../vendor/autoload.php‘
  5. mysql 选择插入语句_带有last_insert_id()的Mysql多行插入 – 选择语句
  6. lnmp构架——对tomcat详解
  7. odbc数据库access丢失_有关使用access数据库,odbc中碰到的一些问题。
  8. selenium调用浏览器进行抓取页面
  9. CCF 201712-3 Crontab
  10. 写论文时引用作者名字
  11. CPP QT实现excel的冻结窗格
  12. Android 12.0 修改系统默认字体的大小
  13. 如何使用真机测试运行HarmonyOS应用
  14. nokia手机的含义
  15. 2022渗透测试-信息收集笔记
  16. android+制作一个锁屏,手机个性锁屏怎么做?教你如何制作DIY手机锁屏图文教程...
  17. 如何让服务端同时支持WebSocket和SSL加密的WebSocket(即同时支持ws和wss)?
  18. AM335x启动流程(bootrom)
  19. 洋姜的腌制方法 怎样腌制洋姜好吃
  20. UltraEdit+注册机+激活方法

热门文章

  1. 西安:食肉种族的最爱
  2. 一个外贸soho的生意经:逆向生意,正向赚钱
  3. 一文读懂交叉熵损失函数
  4. finally语句块
  5. scribe php,Scribe日志收集系统的安装
  6. Windows定时器使用方法
  7. Kali破解路由器Pin码
  8. python生成二维码_用python生成二维码
  9. adfs服务器所属WID管理问题
  10. Linux下采用lapack科学计算包来实现二维矩阵