python排序算法之希尔排序
作者:i阿极 发布时间:2023-03-03 13:50:48
一、前言
相关知识来自《python算法设计与分析》。初级排序算法是指几种较为基础且容易理解的排序算法。初级排序算法包括插入排序、选择排序和冒泡排序3种。相比起初级排序算法,高级排序算法往往有更加复杂的逻辑,但也会有更高的时间或空间效率。其中有些高级排序算法是由初级排序算法优化而来的。
二、算法描述
希尔排序,又叫“缩小增量排序”,是对插入排序进行优化后产生的一种排序算法。它的执行思路是:把数组内的元素按下标增量分组,对每一组元素进行插入排序后,缩小增量并重复之前的步骤,直到增量到达1。
一般来说,希尔排序的时间复杂度为O(n1.3)~O(n2),它视增量大小而定。希尔排序的空间复杂度是O(1),它是一个不稳定的排序算法。进行希尔排序时,元素一次移动可能跨越多个元素,从而可能抵消多次移动,提高了效率。
下面是使用(数组长度/2)作为初始增量的升序希尔排序,每一轮排序过后,增量都缩小一半。
第一步:
如图2-28所示,从第一个元素开始,以增量4来分组。可以看出,当增量为4时,一组内只有两个元素,否则元素的下标就超出了数组的范围。
第二步:
如图2-29所示,对组内的元素进行插入排序。
第三步:
如图2-30所示,继续用相同的方法分组,对组内的元素进行插入排序使得它们有序。
整个数组内的数都被遍历完成后,这一轮排序就结束了。把增量缩小一半,继续进行下一轮排序。
第四步:
如图2-31所示,增量为2时,可以看出每一组内的元素增多了,组的总数减少了。继续对每一组内的元素进行插入排序,直到每一组都遍历完成。
第五步:
最后一轮排序如图2-32所示,再次把增量缩小一半;这时增量为1,相当于对整个数组进行插入排序,也就是最后一轮排序。
最后一轮排序结束后,整个希尔排序就结束了。
三、代码实现
在for循环中,由于每组的第一个元素不用进行插入排序,而它们的下标处于0~step-1,所以从下标step开始遍历。
需要注意的是,如果要模拟流程图中的做法,要使用两个循环:先分组,然后一次性使同组内的元素有序。为了提高效率,我们直接使用一个for循环,每遍历到一个数,就对它所在的组进行插入排序。这样遍历同样符合插入排序的顺序要求。在插入排序中,要改变当前下标的值,所以使用变量ind存储当前下标,防止影响for循环。
普通插入排序等同于增量为1的希尔排序,跨元素的希尔排序实际上只改变了增量,逻辑上与普通插入排序没有区别。
希尔排序代码:
nums = [5,3,6,4,1,2,8,7]
def ShellSort(nums):
step = len(nums)//2 #初始化增量为数组长度的一半
while step > 0: #增量必须是大于0的整数
for i in range(step,len(nums)):#遍历需要进行插入排序的数
ind = i
while ind >= step and nums[ind] < nums[ind-step]: #对每组进行插入排序
nums[ind],nums[ind-step] = nums[ind-step],nums[ind]
ind -= step
step //= 2#增量缩小一半
print(nums)
ShellSort(nums)
运行程序,输出结果为:
[1,2,3,4,5,6,7,8]
总结
来源:https://blog.csdn.net/AOAIYI/article/details/128717484


猜你喜欢
- 一、字符串类型1)字符串是字符的序列表示,根据字符的内容分为单行字符串和多行字符串。2)单行字符串可以由一对单引号(’)
- Git简单介绍Git是一个分布式版本控制软件,最初由Linus Torvalds创作,于2005年以GPL发布。最初目的是为更好地管理Lin
- 目录写在前面基本概念Windows搭建python开发环境从Hello World开始博客总结从大学开始玩python到现在参加工作,已经有
- 本文方案适用于Microsoft Sql Server 2008/2012/2012 r2/2014版本,以下简称MSSQLSERVER。M
- Python是一种解释型、面向对象、动态数据类型的高级程序设计语言,本文就举一例Python类继承的实例。实例代码如下:#! /usr/bi
- 一、SQL注入简介SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编写时的疏忽,通过SQL语句,
- 获取每一天的统计数据做项目的时候需要统对项目日志做分析,其中有一个需求是获取某个给定的时间段内,每一天的日志数据,比如说要获取从2018-0
- 本文实例讲述了python统计文本文件内单词数量的方法。分享给大家供大家参考。具体实现方法如下:# count lines, sentenc
- Python编程中对于某些需要重复调用的程序,可以使用函数进行定义,基本形式为:def 函数名(参数1, 参数2, ……, 参数N):执行语
- 一、wxPython介绍 1.wxPython是Python语言的一套优秀的GUI图形库。wxPytho
- 使用sql的计划任务可以处理一些特殊环境的数据,除了使用windows系统的计划任务来定时处理,不过要配合程序才行,有些事情可以直接使用sq
- 当 http client 返回值为不为空,只读取 response header,但不读 body 内容就执行 response.Body
- class test { &nbs
- 本文实例讲述了php基于协程实现异步的方法。分享给大家供大家参考,具体如下:github上php的协程大部分是根据这篇文章实现的:http:
- 用wrapper封装这样在对象内外都可以访问function MapPool(){ function createMarker(n
- Pandas如何将带有字符串元素的列拆分为多个列。使用以下字符串的方法。str.split():用定界符分割str.extract():按正
- 这些常量在 PHP 的内核中定义。它包含 PHP、Zend 引擎和 SAPI 模
- 本文采用os.walk()和os.listdir()两种方法,获取指定文件夹下的文件名。一、os.walk()模块os中的walk()函数可
- 本文实例讲述了vue实现引入本地json的方法。分享给大家供大家参考,具体如下:当前需要使用的组件:import data from
- 可能很多人遇到过这个错误,当使用setup.py安装python2.7图像处理模块PIL时,python默认会寻找电脑上以安装的vs2008