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 //------- ...
随机推荐
- 【Java深入研究】9、HashMap源码解析(jdk 1.8)
一.HashMap概述 HashMap是常用的Java集合之一,是基于哈希表的Map接口的实现.与HashTable主要区别为不支持同步和允许null作为key和value.由于HashMap不是线程 ...
- RxJava2.0的使用详解
RxJava2.0的使用详解 1,初识RxJava RxJava就是一种用Java语言实现的响应式编程,来创建基于事件的异步程序 RxJava是一个基于事件订阅的异步执行的一个类库,目前比较火的一些技 ...
- Session Cookies随笔
1.对于Session而言 它是用来保存在服务端的信息,可以用来做登录验证,在后台保存有用信息. 一个浏览器访问一个网站,就是建立一个连接,连接信息是独立的,就是在该建立的连接内,保存到Session ...
- Android中使用progurad混淆代码
第一步,取消project.properties中关于progurad的注释,开启progurad,默认的配置文件会被加载进来. proguard.config=${sdk.dir}/tools/pr ...
- Python中DataFrame去重
# 去除重复行数据 keep:'first':保留重复行的第一行,'last':保留重复行的最后一行,False:删除所有重复行df = df.drop_duplicates( subset=['YJ ...
- Appium学习——安装appium Server
安装appium Server 下载地址:百度网盘的下载链接:https://pan.baidu.com/s/1pKMwdfX 下载后, AppiumForWindows.zip 进行解压,点击 ap ...
- asp.net根据参数找不到记录后响应404及显示错误页
在asp.net mvc 中,action方法里根据参数获取数据,假如获取的数据为空,为了响应404错误页,我们可以return HttpNotFound(); 但是在asp.net webform中 ...
- oracle 日期格式化 TO_CHAR (datetime) 修饰语和后缀
Datetime Format Element Suffixes Suffix Meaning Example Element Example Value TH Ordinal Number DDTH ...
- C#中的console类输入输出功能
Console.WriteLine() 直接将括号内内容显示在控制台界面中(相当于C语言printf()吧) Console.ReadLine()获取控制台用户自己输入的内容(功能和C语言scanf( ...
- 解决win10系统dpi放大后,部分网页文字颜色很浅的问题
前段时间,换了个27寸的4k显示器.原始分辨率下文字太小,眼睛估计得看瞎 放大dpi后,这问题,那问题,好多 百度知道,淘宝,这网页文字颜色也非常的浅,看着眼睛很累人 看了半天是字体若的祸 暂时发现A ...