深入理解希尔排序

  • 希尔排序由来
  • 希尔排序思想(升序举例)
  • 希尔排序实现

希尔排序由来

希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing IncrementSort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959年提出而得名。–源自百度百科

  • 希尔排序其实就是一种经过优化的直接插入算法,这种优化使得这种插入排序算法的时间复杂度得到了质变,(这点我们会在下文验证),但其在一些特殊情况下也存在缺陷。

希尔排序思想(升序举例)

  • 要想更好地理解希尔排序,就必须先理解直接插入排序,相比于希尔排序,直接插入排序的思想就简单地多,我们几乎都完成过直接插入排序,逢年过节和三五朋友常常使用棋牌或者麻将进行娱乐,当我们摸到牌以后会自然地去将牌面进行排序,而整理好牌面后再次摸牌得到一张牌插入到牌堆中,这种排序就是直接插入排序。

给定一个整型升序数组a,向其中插入一数字x,如下:

int a[]={2,3,4,6,8,9}
//向a中插入x=5应该如何做?

显然,遍历数组a,找到比x小的第一个值,然后将其插入至x后,同时不影响数组中其它值,故从数组末尾向头遍历
为了方便理解,我们先实现插入一个数字,就使用上述用例:

int end;//数组尾下标
int x;//要插入的数字
while(end>=0)//数组只剩一个元素或者没有元素
{ //倒序遍历if(a[end]>x) //如果元素大于x则后移{a[end+1]=a[end];end--;}else    {break;   //当元素小于x或者数组走到尽头时直接将end的后一位置赋值为x}
}
a[end+1]=x;
  • 插入排序初步思路形成,显然我们的目的不是真的插入一个数进入有序数组,而是在数组中找数进行插入排序,故end和x的值需要确定。
  • 观察单趟排序的代码,为了防止数组越界且保证每个值都被读取一次,end选择为数组每个元素的下标,当数组有n个元素,其最大为n-2,x选择为end后一位元素的值。这样做就是相当于将x插入[0,end]的区间中。显然使用for循环就能很好地完成这一切,至此,插入排序就完成了:
void InsertSort(int* a, int n)
{for (int i = 0; i < n - 1; i++){int end=i;int x=a[end+1];while (end >= 0){if (a[end] > x){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = x;}
}
  • 显然,此排序的时间复杂度为O(N^2) ;
  • 希尔排序的思想在此基础上建立:是否能过通过一些操作,让序列更接近于有序然后再进行插入排序大幅度缩减其时间复杂度?
  • 希尔的思想:希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。

希尔排序实现

设定步长gap,可以将数组分为gap组,然后每个组内进行插入排序使其组内有序,最后整体使用一次插入排序,这时插入排序对一个接近有序的数组进行排序,效率就能很好地体现出
假设步长gap为5,随机给定一个数组,如图:

数组被分成5组,然后每个组内进行插入排序得到:

然后再此基础上再次使用一次插入排序,插入排序的时间复杂度会大大减小(前提是大量的数据,否则难以直接观察到):

思想上,我们是组内一组组进行插入排序,实际实现时只需要每遇见一个元素,然后与其关联为gap步的元素进行插入排序,而直接插入排序就可以理解为希尔排序中gap步长为1的特殊情况,代码应运而生:

void ShellSort(int* a, int n)
{int gap = n;while (gap > 1){gap = gap / 2;for (int i = 0; i < n - gap; i++){int end = i;int x = a[end + gap];while (end >= 0){if (a[end] > x){a[end + gap] = a[end];end-=gap;}else{break;}}a[end + gap] = x;}}
}

这里还有最后一个需要确定的元素就是gap的取值,经过大量测试,发现当数组越无序,gap越要取大,越接近有序gap越取小,故gap不是一个不变的值,这里最外层使用while循环控制,每次预排序都进行gap=gap/2;这使得gap等于1时最后对整个数组进行真正的插入排序就结束。

希尔排序的时间复杂度需要用数学知识来计算,这里附上《数据结构-用面相对象方法与C++描述》一书中殷人昆老师的计算和结论:

【数据结构之排序】-详解希尔排序相关推荐

  1. js排序算法详解-希尔排序

    全栈工程师开发手册 (作者:栾鹏) js系列教程5-数据结构和算法全解 js排序算法详解-希尔排序 希尔排序,直接上图: 像这个算法看图理解起来并不是很难,就像比赛一样,1-6一组,2-7一组,每差5 ...

  2. 【算法知识】详解希尔排序算法

    前言 已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 当待插入元素是一个很小(当需求是从小到大排序时,从大到小排序时此处为很大)直接插入排序需要移动 ...

  3. 希尔排序基础java代码_java 算法之希尔排序详解及实现代码

    摘要:这篇Java开发技术栏目下的"java 算法之希尔排序详解及实现代码",介绍的技术点是"希尔排序详解.实现代码.希尔排序.Java.实现.代码",希望对大 ...

  4. 用数据结构c语言写成绩排序,C语言数据结构 快速排序实例详解

    C语言数据结构 快速排序实例详解 一.快速排序简介 快速排序采用分治的思想,第一趟先将一串数字分为两部分,第一部分的数值都比第二部分要小,然后按照这种方法,依次对两边的数据进行排序. 二.代码实现 # ...

  5. 【Java】插入排序、希尔排序详解

    文章目录 1️⃣必备排序常识 2️⃣插入排序 1.直接插入排序 2.优化后的插入排序 3.折半插入排序 4.性能比较 3️⃣希尔排序 性能比较 1️⃣必备排序常识 稳定性:在原序列中,r[i]=r[j ...

  6. Sorting 排序详解(c语言实现)

    Sorting 排序详解(c语言实现)# 今日突然有任务,明天补充完整. 邮箱:Is_Dmy@163.com期待交流. Hello,各位小伙伴~我是你们的课代表橙橙,今天呢我要给大家分享的是关于内排序 ...

  7. 十大排序详解(java实现)

    十大排序详解(java实现) 一.十大排序算法概述 1.定义 2.分类 3.比较 4.相关概念 二.各算法原理及实现 1.冒泡排序 2.简单选择排序(Selection Sort) 3.直接插入排序( ...

  8. c语言排序常用问题,【更新中】【排序详解】解决排序问题(以C语言为例)

    [更新中][排序详解]解决排序问题(以C语言为例) [更新中][排序详解]解决排序问题(以C语言为例) 文章目录 排序的相关概念 简单排序 一.插入排序: (一)插入排序基本思想 (二)插入排序基本操 ...

  9. 【排序】什么都能排的C语言qsort排序详解【超详细的宝藏级别教程】深度理解qsort排序

    [排序]什么都能排的C语言qsort排序详解[超详细的宝藏级别教程]深度理解qsort排序 作者: @小小Programmer 这是我的主页:@小小Programmer 在食用这篇博客之前,博主在这里 ...

最新文章

  1. 正面迎战英特尔,英伟达要和博世一起卖自动驾驶系统
  2. spring mvc拦截器和mvc:annotation-driven /的详解
  3. 比赛的一道题:SCSHOP1.5代码审计
  4. 6、mysqldump备份数据库(附带实例)
  5. qint64转为qstring qt_Qt项目中TCP通信的实现方式经验总结(服务端部分)
  6. 你是否发现 职业能力危机,请 警惕
  7. 数据库高级知识——查询截取分析(一)
  8. steam夏日促销悄然开始,用Python爬取排行榜上的游戏打折信息
  9. 如何搭建高性能视频网站
  10. 20190807:排序数组删除重复项
  11. LeetCode 394: DecodeString (Java)
  12. Linux 命令(69)—— objcopy 命令
  13. 亲测:真正免费的音频转文字软件
  14. PS PR AI AE LR AU LR ID 下载资源,简单安装,多种方式下载
  15. System进程的启动流程第一部分
  16. SAP数据接口技术类型
  17. C++实现DNS域名解析
  18. vue-版的老虎机抽奖活动效果折腾小记
  19. Promise和事件循环
  20. php使用qq登录api接口,QQ的账号登录及PHP api操作

热门文章

  1. 计算机网络(可当期末复习资料)
  2. 律师也要职业危机?ChatLaw帮助普通人拥有自己的法律顾问
  3. 【图像识别】基于 Haar分类器实现五官定位matlab源码含 GUI
  4. 揭秘华为数字化转型框架:1套方法、4类场景、3个平台能力
  5. Android蓝牙4.0 BLE开发坑总结
  6. UE高级性能剖析技术(1)-- RHI线程(渲染提交)
  7. 开鑫贷鲍建富:经历“排毒” 网贷行业将迎来明媚春天
  8. 网易云音乐歌手歌曲、用户评论、用户信息爬取
  9. 未找到 app.json 中的定义的 pages pages/index/index 对应的 WXML 文件
  10. ESP8266 连接 MQTT