小言_互联网的博客

Python 编程1000例(25):排序算法——希尔排序法

319人阅读  评论(0)

本系列文章通过 1000(一篇文章表示 1 个实例) 个实例 ,为读者提供较为详细的练习题目,以便读者举一反三,深度学习。本系列的文章涉及到 Python 知识点包括:Python 语言基础、运算符和表达式、语句和程序结构、列表和元组、字典和集合、字符串、正则表达式、函数、面向对象编程、模块和包、异常处理和程序调试、文件和目录操作、数据库编程、界面编程、网络编程、WEB 编程、进程和线程、网络爬虫、游戏编程等知识点,由易到难,由浅入深,一步步打下坚实的编程基础。

本系列文章涉及的算法包括搜索、回溯、递归、排序、迭代、贪心、分治和动态规划等,涉及的数据结构包括字符串、列表、指针、区间、队列、矩阵、堆栈、链表、哈希表、线段树、二叉树、二叉搜索树和图结构等。

本系列文章是笔者为适应当前教育改革的创新要求,更好地践行语言类课程,满足实践教学与创新能力培养的需要,阅读大量书籍、各大互联网公司的面试算法、LintCode、LeetCode、九章算法和结合笔者近几年项目经验编写的系列文章,精选了 1000 个趣味性、实用性强的应用实例,从不同难度、不同算法、不同类型和不同数据结构等方面,将实际算法进行总结,希望为 Python 编程人员抛砖引玉。由于笔者经验与水平有限,博文中疏漏及不妥之处在所难免,衷心地希望各位读者在评论区多提宝贵意见及具体的修改建议,以便笔者进一步修改和完善。

一、希尔排序法

希尔排序法是插入排序法的一种,是直接插入排序算法的更高级的改进版本。希尔排序法可以减少插入排序法中数据移动的次数,加快排序的进行,因此它被称为缩小增量排序。希尔排序法排序的原则是将原始数据分成特定间隔的几组数据,然后使用插入排序法对每组数据进行排序,排序之后,再减小间隔距离,然后重复插入排序法对每组数据排序,直到所有数据完成排序为止。希尔排序法最后的结果有两种形式,即递增数列和递减数列。接下来通过一组数据来演示希尔排序法的排序原理。

例如,一组原始数据:60,82,17,35,52,73,54,9,如下图所示:

按照递增进行排序,步骤如下:

步骤1:从上图中可以看出,原始值中有8个数据,将间隔位数设置为8/2=4,即将原始值分为四组数列,分别为:数列1(60,52)、数列2(82,73)、数列3(17,54)、数列4(35,9),如下图所示。将每个数列内的数据进行排序,按照左小右大的原则,将位置错误的数据进行交换,即数列1(52,60)、数列2(73,82)、数列3(17,54)和数列4(9,35)。

说明:间隔位数不一定必须除以2,可以根据自己的需求而定。

步骤2:将步骤1排序后的数列进行插入放置,得出第一次排序结果,如下图所示:

步骤3:接着缩小间隔[(8/2)/2=2],即将原数列分为两组数列,分别为:数列1(52,17,60,54)、数列2(82,35,73,9),如下图所示,然后再对上图中的每个数列内的数据进行排序,按照从小到大的顺序,将位置错误的数据进行交换,即数列1(17,52,54,60)和数列2(9,35,73,82)。

步骤4:将步骤3排序后的数列进行插入放置,得出第二次排序结果,如下图所示:

步骤5:再以[((8/2)/2)]2=1取间隔数,对第二次排序后的数列(如上图所示)中的每一个元素进行排序,得到最后的结果如下图所示:

至此,排序完成。

二、实例:使用希尔排序法进行递增排序

使用希尔排序法为列表:60,82,17,35,52,73,54,9进行递增排序。具体代码如下:

def hill(data):  # 自定义希尔排序函数
    n = len(data)  # 获取数据长度
    step = n // 2  # 让步长从大变小,最后一步必须是1,获取gap的偏移值
    while step >= 1:  # 只要gap在我们的合理范围内,就一直分组下去
        # 按照步长把数据分两半,从步长的位置遍历后面所有的数据,指定j下标的取值范围
        for j in range(step, n):
            while j - step >= 0:  # 拿当前位置的数据,跟当前位置-gap位置的数据进行比较
                if data[j] < data[j - step]:  # 组内大小元素进行替换操作
                    data[j], data[j - step] = data[j - step], data[j]
                    j -= step  # 更新迁移元素的下标值为最新值
                else:  # 否则的话,不进行替换
                    break
        step //= 2  # 每执行完毕一次分组内的插入排序,对gap进行/2细分


data = [60, 82, 17, 35, 52, 73, 54, 9]  # 定义列表并初始化
print("原始数据:")
print(data)  # 输出原数据
print("---------------------------------")
hill(data)  # 调用自定义希尔排序函数
print("排序之后的数据:")
print(data)  # 输出排序之后数据
print("---------------------------------")

程序运行结果如下图所示:

三、练习:热门游戏下载量排名

游戏是很多人消遣时间的一种方式,在手机的软件安装商店里,也有各类游戏。假设有6款游戏,它们的下载量(单位是万次)分别是:3009,2578,3044,9336,1111,5312。利用希尔排序法为下载量按照从高到低顺序进行排序。具体代码如下:

def hill(data):  # 自定义希尔排序函数
    n = len(data)  # 获取数据长度
    step = n // 2  # 让步长从大变小,最后一步必须是1,获取gap的偏移值
    while step >= 1:  # 只要gap在我们的合理范围内,就一直分组下去
        # 按照步长把数据分两半,从步长的位置遍历后面所有的数据,指定j下标的取值范围
        for j in range(step, n):
            while j - step >= 0:  # 拿当前位置的数据,跟当前位置-gap位置的数据进行比较
                if data[j] > data[j - step]:  # 组内大小元素进行替换操作
                    data[j], data[j - step] = data[j - step], data[j]
                    j -= step  # 更新迁移元素的下标值为最新值
                else:  # 否则的话,不进行替换
                    break
        step //= 2  # 每执行完毕一次分组内的插入排序,对gap进行/2细分


data = [3009, 2578, 3044, 9336, 1111, 5312]  # 定义列表并初始化
print("六款游戏下载量如下:")
print(data)  # 输出原数据
print("========================================")
hill(data)  # 调用自定义希尔排序函数
print("从高到低排序之后的下载量如下:")
print(data)  # 输出排序之后数据
print("========================================")

程序运行结果如下图所示:

感谢您阅读本篇博文,希望本文能成为您编程路上的领航者。祝您阅读愉快!


    好书不厌读百回,熟读课思子自知。而我想要成为全场最靓的仔,就必须坚持通过学习来获取更多知识,用知识改变命运,用博客见证成长,用行动证明我在努力。
    如果我的博客对你有帮助、如果你喜欢我的博客内容,请 点赞评论收藏 一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。
 编码不易,大家的支持就是我坚持下去的动力。点赞后不要忘了 关注 我哦!


转载:https://blog.csdn.net/xw1680/article/details/115985367
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场