堆排序-Python实现

简述

堆排序(Heap Sort)是一种基于比较的排序算法,它利用堆这种数据结构所设计的一种排序算法。堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。

堆排序中的堆有大顶堆小顶堆两种。他们都是完全二叉树。

完全二叉树是指除了最后一层外,每一层都是完全填充的,并且最后一层的右边都是空的二叉树。大顶堆和小顶堆都是特殊的完全二叉树,它们的特点分别是每个节点的值都不小于(或不小于)其子节点的值,和每个节点的值都不大于(或不小于)其子节点的值。

将该堆按照排序放入列表

  • 大顶堆:所有的父节点的值都比孩子节点大,叶子节点值最小。root 根节点是第一个节点值最大公式表示:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
  • 小顶堆:和大顶堆相反,所有父节点值,都小于子节点值,root 根节点是 第一个节点值最小公式表示:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]

ok,了解了这些定义。接下来,我们来看看堆排序的基本思想及基本步骤。

堆排序基本思想及步骤

堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

在堆的结构中,堆中的最小值(最大值)总是位于堆的根结点。在堆排序中主要分为三步:
(1)创建大顶堆(BuildMaxHeap):将待排序元素列中的所有元素进行排列,生成一个大顶堆;
(2)将堆顶元素与末尾元素进行交换,将最大元素“沉”到元素列末端;
(3)调整顶堆,使其满足大顶堆定义;
(4)重复(2)(3)步骤,直至元素列有序。

以大顶堆为例

构造大顶堆

  • 如何调整
    我们从最后一个非叶子节点处开始调整。最后一个非叶子节点是最后一个叶子节点的父节点。
    若父节点的下标为 i ,那么左孩子节点下标为 i × 2 + 1,右孩子节点下标为 i × 2 + 2。
    设元素列的长度为 N,因为下标从0开始,所以最后一个叶子节点的下标是 N - 1。
    分两种情况:第一种是最后一个叶子节点是左孩子节点,那么 n - 1 = i × 2 + 1,即 i = n / 2 - 1
    第二种情况是最后一个叶子节点是右孩子节点(此时 n 是奇数)那么 n - 1 = i × 2 + 2,即 i = ( n - 1 ) / 2 - 1 = n / 2 - 1(向下取整)
    综上,最后一个非叶子节点的下标是 n / 2 - 1

  • 构造大根堆

    以升序排序序列 [20,50,20, 40, 70,10,80, 30,60]为例

    它对应的二叉树结构如下:

在我们的例子中,最后一个非叶子节点的下标是 9 / 2 - 1 = 3,因此调整顺序为:3–>2 -->1 -->0。

  1. 从最后一个父节点开始,将父节点、他所有的子节点中的最大值交换到父节点。父节点:3

  1. 将倒数第二个父节点同理交换,父节点:2

  1. 继续调整父节点:1

  1. 最后是根节点:0

  1. 注意很重要:务必注意-承接第3步。
    假设根节点值为:10, 当他和两个子节点70, 80。

父节点和两子节点中的大的(80)交换后位于父节点2:原来80的位置。

可是他还有子节点,且子节点中的值比根节点大,那就还需要以他为父节点构造一次,与子节点6 值为20交换一次。

同理在其他所有父节点的构造中都需要判断调整
忽略第五步。构造好的的大顶堆如下:

堆排序简略版

基本思路:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。可称为有序区,然后将剩余n-1个元素重新构造成一个堆,估且称为堆区(未排序)。这样会得到n个元素的次小值。重复执行,有序区从:1—>n,堆区:n–>0,便能得到一个有序序列了。
每次将堆顶(根节点)最的的元素和堆尾列表最后一个元素交换,80 和40交换
即上面说的堆区(未排序):n–>0最大元素(根节点),和有序区从:1—>n,最后一个元素交换

按照上面原理继续排序,70, 30 交换。然后调整堆

堆顶元素60尾元素20交换后–>调整堆

最后结果

堆排序-python代码实现

现在排序这么一个序列:list_ = [4, 7, 0, 9, 1, 5, 3, 3, 2, 6]

    """堆排序  heap_sort4/   \7      0/  \    / \9    1   5   3/ \   /3   2  6list_ = [4, 7, 0, 9, 1, 5, 3, 3, 2, 6]"""

代码实现一

    def swap(data, root, last):data[root], data[last] = data[last], data[root]#调整父节点 与孩子大小, 制作大顶堆def adjust_heap(data, par_node, high):new_par_node = par_nodej = 2*par_node +1   #取根节点的左孩子, 如果只有一个孩子 high就是左孩子,如果有两个孩子 high 就是右孩子while j <= high: #如果 j = high 说明没有右孩子,high就是左孩子if j < high and data[j] < data[j+1]: #如果这儿不判断 j < high 可能超出索引# 一个根节点下,如果有两个孩子,将 j  指向值大的那个孩子j += 1if data[j] > data[new_par_node]: #如果子节点值大于父节点,就互相交换data[new_par_node], data[j] = data[j], data[new_par_node]new_par_node = j #将当前节点,作为父节点,查找他的子树j = j * 2 + 1else:# 因为调整是从上到下,所以下面的所有子树肯定是排序好了的,#如果调整的父节点依然比下面最大的子节点大,就直接打断循环,堆已经调整好了的break# 索引计算: 0 -->1 --->....#    父节点 i   左子节点:2i +1  右子节点:2i +2  注意:当用长度表示最后一个叶子节点时 记得 -1#    即 2i + 1 = length - 1 或者 2i + 2 = length - 1#    2i+1 + 1 = length 或 2i+2 + 1 = length#    2(i+1)=length 或 2(i+1)+1 = length#    设j = i+1  则左子节点(偶数):2j = length 和 右子节点(基数):2j+1 = length#    2j//2 = j == (2j+1)//2 这两个的整除是一样的,所以使用length//2 = j 然后 i + 1 = j#    i = j-1  = length//2 -1  #注意左子节点:2i+1 //2 =i  而右子节点:(2i+2)//2 = i+1 # 从第一个非叶子节点(即最后一个父节点)开始,即 list_.length//2 -1(len(list_)//2 - 1)# 开始循环到 root 索引为:0 的第一个根节点, 将所有的根-叶子 调整好,成为一个 大顶堆def heap_sort(lst):"""根据列表长度,找到最后一个非叶子节点,开始循化到 root 根节点,制作 大顶堆:param lst: 将列表传入:return:"""length = len(lst)last = length -1  #最后一个元素的 索引last_par_node = length//2 -1while last_par_node >= 0:adjust_heap(lst, last_par_node, length-1)last_par_node -= 1  #每调整好一个节点,从后往前移动一个节点# return lstwhile last > 0:#swap(lst, 0, last)lst[0], lst[last] = lst[last],lst[0]# 调整堆让 adjust 处理,最后已经排好序的数,就不处理了adjust_heap(lst, 0, last-1)last -= 1return lst #将列表返回if __name__ == '__main__':list_ = [4, 7, 0, 9, 1, 5, 3, 3, 2, 6]heap_sort(list_)print(list_)#最后结果为:[0, 1, 2, 3, 3, 4, 5, 6, 7, 9]

代码实现二

    import mathdef heap_sort(a):al = len(a)def heapify(a, i):left = 2 * i + 1right = 2 * i + 2largest = iif left < al and a[left] > a[largest]:largest = leftif right < al and a[right] > a[largest]:largest = rightif largest != i:a[i], a[largest] = a[largest], a[i]heapify(a, largest)# 建堆for i in range(math.floor(len(a) / 2), -1, -1):heapify(a, i)# 不断调整堆:根与最后一个元素for i in range(len(a) - 1, 0, -1):a[0], a[i] = a[i], a[0]al -= 1heapify(a, 0)return aif __name__ == '__main__':list_ = [4, 7, 0, 9, 1, 5, 3, 3, 2, 6]heap_sort(list_)print(list_)#最后结果为:[0, 1, 2, 3, 3, 4, 5, 6, 7, 9]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2774779.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

JCIM | MD揭示PTP1B磷酸酶激活RtcB连接酶的机制

Background 内质网应激反应&#xff08;UPR&#xff09; 中的一个重要过程。UPR是由内质网中的三种跨膜传感器&#xff08;IRE1、PERK和ATF6&#xff09;控制的细胞应激反应&#xff0c;当内质网中的蛋白质折叠能力受到压力时&#xff0c;UPR通过减少蛋白质合成和增加未折叠或错…

零基础学Python(8)— 流程控制语句(上)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。流程控制语句是编程语言中用于控制程序执行流程的语句&#xff0c;本节课就带大家认识下Python语言中常见的流程控制语句&#xff01;~&#x1f308; 目录 &#x1f680;1.程序结构 &#x1f680;2.最简单的if语句 &a…

论 Scratch 版“愤怒的小鸟”的资源(10000 余块代码)

资源链接 “愤怒的小鸟”资源&#xff1a;https://download.csdn.net/download/leyang0910/88820527 游戏 SJA 分析及&#xff1a;角色数量&#xff1a;12&#xff0c;素材数量&#xff1a;214&#xff0c;积木数量&#xff1a;1442&#xff0c;音频数量&#xff1a;11 “愤怒…

【复现】万户 ezOFFICE SQL注入漏洞_42

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 万户ezOFFICE协同管理平台分为企业版和政务版。 解决方案由五大应用、两个支撑平台组成&#xff0c;分别为知识管理、工作流程、沟…

考研数据结构笔记(5)

单链表的查找 按位查找(O(n))按值查找(O(n))单链表长度(O(n))小结 基于带头结点的代码 按位查找(O(n)) 按值查找(O(n)) 单链表长度(O(n)) 小结

牛客网SQL进阶137:第二快/慢用时之差大于试卷时长一半的试卷

官网链接&#xff1a; 第二快慢用时之差大于试卷时长一半的试卷_牛客题霸_牛客网现有试卷信息表examination_info&#xff08;exam_id试卷ID, tag试卷类别,。题目来自【牛客题霸】https://www.nowcoder.com/practice/b1e2864271c14b63b0df9fc08b559166?tpId240 0 问题描述 试…

EMQX Enterprise 5.3 发布:审计日志、Dashboard 访问权限控制与 SSO 一站登录

EMQX Enterprise 5.3.0 版本已正式发布&#xff01; 新版本带来多个企业特性的更新&#xff0c;包括审计日志&#xff0c;Dashboard RBAC 权限控制&#xff0c;以及基于 SSO&#xff08;单点登录&#xff09;的一站式登录&#xff0c;提升了企业级部署的安全性、管理性和治理能…

[算法前沿]--061-生成式 AI 的发展方向,是 Chat 还是 Agent?

什么是AI Agent (LLM Agent) AI Agent 的定义 AI Agent是一种超越简单文本生成的人工智能系统。它使用大型语言模型&#xff08;LLM&#xff09;作为其核心计算引擎&#xff0c;使其能够进行对话、执行任务、推理并展现一定程度的自主性。简而言之&#xff0c;Agent是一个具有…

互联网加竞赛 基于深度学的图像修复 图像补全

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学的图像修复 图像补全 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-se…

JMeter测试工具(性能篇)

自动化脚本 设置全局变量 断言 接口弱压力测试 模拟半小时之内1000个用户访问服务器资源&#xff0c;要求平均响应时间在3000ms内&#xff0c;且错误率为0 模拟100个用户同时访问服务器资源&#xff0c;要求平均响应时间在3000毫秒内&#xff0c;且错误率为0 高并发 模拟2个…

专业130+总分410+苏州大学837信号系统与数字逻辑考研经验电子信息与通信,真题,大纲,参考书

今年考研总分410&#xff0c;专业837信号系统与数字逻辑130&#xff0c;整体每门相对比较均衡&#xff0c;没有明显的短板&#xff0c;顺利上岸苏大&#xff0c;总结一下自己这大半年的复习经历&#xff0c;希望可以对大家有所帮助&#xff0c;也算是对自己考研做个总结。 专业…

高中学校档案室主要做什么

高中学校档案室主要负责管理、保存和维护学校的各类档案文件。具体工作内容包括&#xff1a; 1. 档案收集&#xff1a;负责收集学校各个部门的档案文件&#xff0c;包括学生档案、教职工档案、教学档案、行政档案等。 2. 档案分类和整理&#xff1a;对收集到的档案文件进行分类…

【Spring源码解读!底层原理进阶】【上】探寻Spring内部:BeanFactory和ApplicationContext实现原理揭秘✨

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;底层原理高级进阶》 &#x1f680…

诺奖经济学家称AI将取代STEM专业工作!Altman:人类无需工作,我给发钱

最近&#xff0c;2010年诺贝尔经济学奖得主&#xff0c;伦敦政治经济学院&#xff08;LSE&#xff09;教授Christopher Pissarides公开表态&#xff0c;在不远的未来&#xff0c;传统意义上的「数理化」学科知识和技能&#xff0c;都将会被AI取代。 这位劳动力市场经济学家警告…

相机图像质量研究(10)常见问题总结:光学结构对成像的影响--光圈

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

《山雨欲来-知道创宇 2023 年度 APT 威胁分析总结报告》

下载链接: https://pan.baidu.com/s/1eaIOyTk12d9mcuqDGzMYYQ?pwdzdcy 提取码: zdcy

C++入门全集(1):初窥门径

一、前言 C是一种计算机高级程序设计语言&#xff0c;它在C语言的基础上进行了进一步的扩充和完善&#xff0c;并增加了许多有用的库&#xff0c;是一种面向对象的程序设计语言。 所以&#xff0c;C是兼容C语言语法的。 我打算把所有C入门需要学习的知识整合成一个全集&…

在c++中最重要的语法:类。第一章,什么是类,如何认识类,怎么使用类?

这一篇&#xff0c;简单介绍类的基本认知&#xff0c;和细节。 在c中&#xff0c;我们很多时间都要和类去打交道。它也是c相较于c新增的一个比较好用的语法。 类的定义如下&#xff1a; class A{private:成员函数或者成员属性public:成员函数或者成员属性protected:成员函数…

【C++】友元、初始化列表、内部类、static修饰成员详解

文章目录 前言1. 构造函数不为人知的那些事1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字 2. static成员2.1 概念2.2 特性2.3 小总结 3. C11 成员变量初始化新用法4. 友元4.1 友元函数4.2 友元类 5. 内部类5.1概念及特性 总结 前言 提示&#xff1a;这里可以添加本文要…

IntelliJ IDEA 2023.3发布,AI 助手出世,新特性杀麻了!!

目录 关键亮点 对 Java 21 功能的完全支持 调试器中的 Run to Cursor&#xff08;运行到光标)嵌入选项 带有编辑操作的浮动工具栏 用户体验优化 Default&#xff08;默认&#xff09;工具窗口布局选项 默认颜色编码编辑器标签页 适用于 macOS 的新产品图标 Speed Sear…