Python排序算法——希尔排序(Shell’s Sort)
有趣的事,Python永远不会
如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10793487.html
一、希尔排序(Shell’s Sort)
希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本,它与插入排序的不同之处在于,它会优先比较距离较远的元素,该方法因D.L.Shell于1959年提出而得名。
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
1、原理
希尔排序的整体思想是将固定间隔的几个元素之间排序,然后再缩小这个间隔。这样到最后数列就成为了基本有序数列,而前面我们讲过插入排序对基本有序数列排序效果较好。
计算一个增量(间隔)值
对元素进行增量元素进行比较,比如增量值为7,那么就对0,7,14,21…个元素进行插入排序
然后对1,8,15…进行排序,依次递增进行排序
所有元素排序完后,缩小增量比如为3,然后又重复上述第2,3步
最后缩小增量至1时,数列已经基本有序,最后一遍普通插入即可
图片来源:https://www.cnblogs.com/chengxiao/p/6104371.html
2、希尔排序详解
- 希尔排序在排序前:将一个序列分成了好几个序列
- 在第一趟排序时:将这几个序列做插入排序。排序后,部分较大的数字往后靠,部分较小的数字往前靠
- 在第二趟排序时:将这个序列又分了好几个序列做插入排序(但比第一次分的数要少,ps:如果第一次分5个,第二次可能就2个了)。排序后,部分较大的数字往后靠,部分较小的数字往前靠
- ................
- 在第n趟排序时:将这个序列又分了好几个序列(直到剩下一个序列),从宏观上看,此序列就基本是有序的了。这时就用简单插入排序将数列直至已序
从直观上看希尔排序:就是把数列进行分组(不停使用插入排序),直至从宏观上看起来有序,最后插入排序起来就容易了(无须多次移位或交换)。
3、举例
举个例子,假设我现在有一个数列
[11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22] ,使用希尔排序的详细步骤:
- 首先,gap = length / 2=7,数组分为7组
[11, 11],[ 99 , 33], [33, 36], [69, 39],[ 77, 66],[88, 44], [55, 22]
- 然后,对7组分别插入排序,像33,39,66,44,22这些元素被调到前面,
1 [11, 11],[ 33 , 99], [33, 36], [39, 69],[ 66, 77],[44, 88], [22, 55]
- 接着,数组变为
[11, 11,33 , 99, 33, 36, 39, 69, 66, 77,44, 88, 22, 55]
gap = length / 2=3,数组分为3组,
[11,99,39,77,22],[11,33,69,44,55],[33,36,66,88]
- 以此类推,gap = length / 2=1列表变为
1 [11,22,39,77,99,11,33,44,55,69,33,36,66,88]
- 最终对数组微调,得到列表
1 [11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]
二、代码
代码用jupyternotebook实现
在希尔排序的理解时,我们倾向于对于每一个分组,逐组进行处理,但在代码实现中,我们可以不用这么按部就班地处理完一组再调转回来处理下一组(这样还得加个for循环去处理分组)比如[5,4,3,2,1,0] ,首次增量设gap=length/2=3,则为3组[5,2] [4,1] [3,0],实现时不用循环按组处理,我们可以从第gap个元素开始,逐个跨组处理。同时,在插入数据时,可以采用元素交换法寻找最终位置,也可以采用数组元素移动法寻觅。希尔排序的代码比较简单,如下:
def shell_sort(arr):
"""希尔排序"""
# 取整计算增量(间隔)值
gap = len(arr) // 2
while gap > 0:
# 从增量值开始遍历比较
for i in range(gap, len(arr)):
j = i
current = arr[i]
# 元素与他同列的前面的每个元素比较,如果比前面的小则互换
while j - gap >= 0 and current < arr[j - gap]:
arr[j] = arr[j - gap]
j -= gap
arr[j] = current
# 缩小增量(间隔)值
gap //= 2
return arr shell_sort([11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]) # 返回结果[11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]
三、特点
比较性:排序时元素之间需要比较,所以为比较排序
稳定性:因为希尔排序是间隔的插入,所以存在相同元素相对顺序被打乱,所以是不稳定排序
时间复杂度: 最坏时间复杂度O(n^2)平均复杂度为O(n^1.3)
空间复杂度:只需要常数个辅助单元,所以空间复杂度也为O(1)
记忆方法:插入排序是每轮都是一小步,希尔排序是先大步后小步,它第一个突破O(n2)的排序算法。联想起阿姆斯特朗登月之后说:这是我个人一小步,却是人类迈出的一大步。
结果
Successfully !!!
有趣的事,Python永远不会缺席!还不来加我,瞅什么瞅。

Python排序算法——希尔排序(Shell’s Sort)的更多相关文章
- 排序算法--希尔排序(Shell Sort)_C#程序实现
排序算法--希尔排序(Shell Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难 ...
- 数据结构和算法(Golang实现)(22)排序算法-希尔排序
希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机 ...
- 使用 js 实现十大排序算法: 希尔排序
使用 js 实现十大排序算法: 希尔排序 希尔排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- C数据结构排序算法——希尔排序法用法总结(转http://www.cnblogs.com/skywang12345/p/3597597.html)
希尔排序介绍 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进.该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 希尔排序实质上是一种分组插入方法.它 ...
- js 实现排序算法 -- 希尔排序(Shell Sort)
原文: 十大经典排序算法(动图演示) 希尔排序 1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版.它与插入排序的不同之处在于,它会优先比较距离较远的元素.希尔排序又叫缩 ...
- 八大排序算法——希尔(shell)排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 简单插 ...
- 排序算法-希尔排序(Java)
package com.rao.sort; import java.util.Arrays; /** * @author Srao * @className ShellSort * @date 201 ...
- JavaScript排序算法——希尔排序
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Java排序算法——希尔排序
package sort; //================================================= // File Name : ShellSort //------- ...
随机推荐
- ajax提交form表单问题
form表单提交数据可以省下大量大量获取元素的代码,局部刷新时也可以用ajax提交form表单,但是要先把表单序列化,再把后台javaBean对象序列化,但是你有可能前后台都执行了系列化,但是后台还是 ...
- domOperation.js
// 可视宽高var ch = document.documentElement.clientHeightvar cw = document.documentElement.clientWidth / ...
- [总结]jQuery之选择器集合
jQuery 的选择器可谓之强大无比,常用的元素查找方法: $("#myELement") //选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是my ...
- 1788:Pell数列
1788:Pell数列 查看 提交 统计 提问 总时间限制: 3000ms 内存限制: 65536kB 描述 Pell数列a1, a2, a3, ...的定义是这样的,a1 = 1, a2 = 2 ...
- 最全最新的opencv版本下载
opencv和opencv_contrib版本都可以到这个github下载 包括编译好的vc14和vc15window版本 还有源码版,可以自行cmake
- GIS性能策略
当一个地理平台上线运行,我们经常会遇到这些问题:1.系统刚上线时速度较快,一段时间后访问较慢?2.在地理平台目前的配置下,发布多少个服务才合理?一个服务配置多少个实例数才合适?这些问题,都涉及整个地理 ...
- python自动化开发-8
进程与线程 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程. 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位. ...
- node中__dirname、__filename、process.cwd()、process.chdir()表示的路径
直接上结论:__dirname 表示当前文件所在的目录的绝对路径__filename 表示当前文件的绝对路径module.filename ==== __filename 等价process.cwd( ...
- 洗礼灵魂,修炼python(56)--爬虫篇—知识补充—编码之url编码
其实在最前面的某一篇博文里,是绝对提过编码的,有ASCII,有UTF-8,有GB2312等等,这些我绝对说过的. url编码 首先,Http协议中参数的传输是"key=value" ...
- java针对不同方法的分页
一.常见的分页实现方式 ①使用List接口中的subList(int startIndex,int endIndex)方法实现分页 ②直接使用数据库SQL语句实现分页 ③使用hibernate等框架实 ...