堆的基本概念

news2024/10/6 14:37:41
  • 堆是一个完全二叉树
    • 完全二叉树的要求,除了最后一层,其他层的节点个数都是满的,最后一层的节点都靠左排列
  • 堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值
    • 堆中每个节点的值都大于等于(或者小于等于)其左右子节点的值
最大堆
  • 结点的键值小于等于其父结点的键值
  • 请添加图片描述
最小堆
  • 结点的键值大于等于其父结点的键值
  • 请添加图片描述
已知父结点
    • 左孩子结点: 2 * 父结点 + 1
    • 右孩子结点: 2 * 父结点 + 2
    • 左孩子结点: 2 * 父结点
    • 右孩子结点: 2 * 父结点 + 1
已知孩子结点
    • 父结点: 孩子结点 - 1 / 2
    • 父结点: 孩子结点 / 2
堆化(heapify)
  • 堆化实际上有两种,从下往上从上往下
    • 从下往上
      • 请添加图片描述

      • 就是顺着节点所在的路径,向上或者向下,对比,然后交换

      • 请添加图片描述

      • 让新插入的节点与父节点对比大小。如果不满足子节点小于等于父节点的大小关系,就互换两个节点

      • 一直重复这个过程,直到父子节点之间满足刚说的哪种大小关系

    • 从上往下
      • 请添加图片描述

      • 把最后一个节点放到堆顶,然后利用同样的父子节点对比的方法

      • 对于不满足父子节点大小关系的,互换两个节点,并且重复进行这个过程,直到父子节点之间满足大小关系为止

    • 时间复杂度
      • 一个包含n个节点的完全二叉树,树的高度不会超过log2n
      • 堆化的过程是顺着节点所在路径比较的,所以堆化的时间复杂度跟树的高度成正比,也就是O(logn)
      • 插入数据和删除堆顶元素的主要逻辑是堆化,所以,往堆中插入一个元素和删除堆顶元素的时间复杂度都是O(logn)
如何基于堆实现排序
  • 时间复杂度: O(nlogn)
  • 建堆
    • 堆排序是原地排序,不借助另一个数组,就在原数组上操作

    • 第一种,在堆中插入一个元素的思路

      • 通过从下往上的插入方式,把n个数据插入数组中,形成堆
    • 第二种,与第一种相反

      • 是从后往前处理数组,并且每个数据都是从上往下堆化

      • 请添加图片描述

      • 请添加图片描述

    • 代码实现

      • 请添加图片描述

      • 这段代码里,从下标 n / 2 开始到1的数据进行堆化

      • 下标 n / 2 +1 到 n 的节点是叶子节点,不需要堆化

      • 从上图代码中,可以看出每个节点的堆化时间复杂度: O(logn)

    • 时间复杂度

      • 每个节点堆化的时间复杂度是O(logn), 那么 n / 2 + 1的总时间复杂度是 O(nlogn)?

      • 请添加图片描述

      • 求和公式

        • 请添加图片描述

        • 求解

          • 把公式左右都乘以2,得S2, 然后 S2 - S1 = S

          • 请添加图片描述

          • 求解等比数列

          • 请添加图片描述

          • 因为 h = log2n ,代入公式S,得到S = O(n)

        • 解答过程

          • 请添加图片描述
      • 所以,建堆时间复杂度为:O(n)

  • 排序
    • 请添加图片描述

    • 时间复杂度

      • 整个堆排序的过程,都只需要极个别临时存储空间,所以堆排序是原地排序算法
      • 堆排序包括建堆和排序两个操作,建堆过程的时间复杂度是 O(n),排序过程的时间复杂度是 O(nlogn),所以,堆排序整体的时间复杂度是 O(nlogn)
      • 堆排序不是稳定的排序算法,因为在排序的过程,存在将堆的最后一个节点跟堆顶节点互换的操作,所以就有可能改变值相同数据的原始相对顺序
为什么快速排序比堆排序性能更好?
  • 堆排序数据访问的方式没有快速访问友好
    • 对于快速排序来说,数据是顺序访问的。而对于堆排序来说,数据是跳着访问的
      • 比如数据的堆化
        • 请添加图片描述

        • 对堆顶节点进行堆化,会依次访问数组下标为1,2,4,8的元素,而不是像快速排序那样,局部顺序访问,所以,这样对CPU缓存是很不友好的

    • 对于同样的数据,在排序过程中,堆排序算法数据交换次数要多于快速排序
      • 在讲排序的时候,提过两个概念,有序度和逆序度
      • 对于基于比较的排序算法来说,整个排序过程就是由两个基本的操作组成的,比较和交换(或移动)
      • 快速排序
        • 快速排序数据交换的次数不会比逆序度多
      • 堆排序
        • 堆排序的第一步是建堆,建堆的过程会打乱数据原有的相对先后顺序,导致原数据有序度降低

        • 请添加图片描述

        • 对于一组已经有序的数据来说,经过建堆之后,数据反而变得更加无序了

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

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

相关文章

C#(C Sharp)学习笔记_封装【十八】

什么是封装? 封装是面向对象思维的三大特性之一。封装是将数据和对数据进行操作的函数绑定到一起的机制。它隐藏了对象的内部状态和实现细节,只对外提供必要的接口,从而确保对象内部状态的完整性和安全性。封装的主要目的是增强安全性和简化…

登录MySQL方式

登录MySQL方式 方式一:通过MySQL自带的客户端 MySQL 客户端输入命令即可 方式二:通过window自带的客户端 从命令端(cmd)进入 mysql -h localhost -P 3306 -u root -p Enter password:密码登录方式: mysql -h 主…

【LeetCode最详尽解答】11-盛最多水的容器 Container-With-Most-Water

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家! 链接: 11-盛最多水的容器 直觉 这个问题可以通过可视化图表来理解和解决。 通过图形化这个…

基于51单片机万年历设计—显示温度农历

基于51单片机万年历设计 (仿真+程序+原理图+设计报告) 功能介绍 具体功能: 本系统采用单片机DS1302时钟芯片LCD1602液晶18b20温度传感器按键蜂鸣器设计而成。 1.可以显示年月日、时分秒、星期、温度值。…

mySql的事务(操作一下)

目录 1. 简介2. 事务操作3. 四大特性4. 并发事务问题5. 脏读6. 不可重复读7. 幻读事务隔离级别参考链接 1. 简介 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作…

机器学习(V)--无监督学习(二)主成分分析

当数据的维度很高时,很多机器学习问题变得相当困难,这种现象被称为维度灾难(curse of dimensionality)。 在很多实际的问题中,虽然训练数据是高维的,但是与学习任务相关也许仅仅是其中的一个低维子空间&am…

【Java】Object、Objects、包装类、StringBuilder、StringJoiner

目录 1.API2.Object类3.Objects类4.包装类4.1包装类概述4.2包装类的其他常见操作 5.StringBuilder 可变字符串5.1概述5.2StringBuilder案例 6.StringJoiner 1.API API:应用程序编程接口,全称application programing interface,即Java已经写好…

分享一个 .NET Core 使用选项方式读取配置内容的详细例子

前言 在 .NET Core 中,可以使用选项模式(Options Pattern)来读取和管理应用程序的配置内容。 选项模式通过创建一个 POCO(Plain Old CLR Object)来表示配置选项,并将其注册到依赖注入容器中,方…

Spring AI探索

Spring AI概述 该Spring AI项目旨在简化包含人工智能功能的应用程序的开发,避免不必要的复杂性。 该项目从著名的 Python 项目(例如 LangChain 和 LlamaIndex)中汲取灵感,但 Spring AI 并非这些项目的直接移植。该项目的成立基于…

Linux内核编程(五)ioctl驱动编写

本文目录 一、系统层和内核层接口1. ioctl系统层接口2. ioctl内核层接口 二、标准 unlocked_ioctl 接口的命令合成三、代码编程 ioctl 主要用于实现对硬件设备控制类操作,实现 write 和 read 不太好实现的功能。 ioctl 是一个强大的工具,可以用于实现复杂…

​单级高频谐振小放

目录 高频交流等效电路 质量指标 增益 通频带 选择性 高频交流等效电路 质量指标 增益 YL撇是怎么来的。 通频带 选择性

Spark常见的可以优化的点

Shuffle 复用 # 1.以下操作会复用的shuffle结果,只会读一遍数据源 val rdd1 sc.textFile("hdfs://zjyprc-hadoop/tmp/hive-site.xml").flatMap(_.split(" ")).map(x > (x,1)).reduceByKey(_ _).filter(_._2 > 1) rdd1.count() rdd1.fil…

基于dagger平台实现资源位的接口自动化

文章目录 什么是dagger平台?什么是资源位?什么是接口自动化?如何实现接口自动化?内部调用关系基本概念互相引用关系 目录结构具体实现任务:Task用例:Case场景:Scene接口:Api 监控与数…

基于Itô扩散过程的交易策略偏微分方程matlab求解与仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于It扩散过程的交易策略偏微分方程,提出了一种确定It扩散过程。通过根据的第一次通过时间来确定问题在这个过程中,我们推导出交易长度的分布函数和密…

如何通过Outlook大附件插件,加强外发附件的安全性和管控力度?

因邮件的便捷性和普遍性,企业间业务往来通常会采取邮箱业务,沟通使用成本也比较低,但容易出现附件太大无法上传的问题。Outlook大附件插件是为解决邮件系统中附件大小限制问题而开发的一系列工具。 使用邮件发送附件时,可能会遇到…

R调用Taxonkit展示系统发育信息

Introduction TaxonKit是一个用于处理生物分类学数据的命令行工具。 它的主要功能是处理NCBI的生物分类学数据,包括对分类单元(如物种、属、科等)的查找、分类单元的上下位关系查询、分类单元名称的标准化等。 为了方便R社区用户&#xff0…

QuickLook最强大的C#开源文件预览神器

功能特点: 快速预览:用户只需选中文件并按下空格键,即可立即查看文件内容,无需打开特定应用程序或软件。 多格式支持:QuickLook支持预览几乎所有常见的文件类型,包括但不限于: 图像&#xff1…

【计算机网络】已解决:“‘ping‘ 不是内部或外部命令,也不是可运行的程序或批处理文件”报错

文章目录 一、问题分析背景二、可能出错的原因三、错误代码示例四、正确解决方法与示例五、注意事项 已解决“‘ping’ 不是内部或外部命令,也不是可运行的程序或批处理文件”报错 一、问题分析背景 在Windows操作系统中,ping 命令是一个常用的网络诊断…

STM32CubeMX配置-外部中断配置

一、简介 MCU为STM32G070,配置为上升沿触发外部中断,在上升沿外部中断回调函数中进行相关操作。 二、外部中断配置 查看规格书中管教描述,找到I/O对应的外部中断线,然后进行如下上升沿触发外部中断配置。 三、生成代码 调用上升沿…

【Linux】进程_6

文章目录 五、进程8. 进程地址空间 未完待续 五、进程 8. 进程地址空间 上图可能很多人都看过了,这里再来验证一下: 验证位置: 验证堆栈的生长方向: 在上面的空间布局图中,有一个疑问,画的空间是 内存…