算法笔记p335堆

目录

    • 定义堆
    • 建堆(以大顶堆为例)
    • 删除堆顶元素
    • 插入元素
  • 堆排序
    • 排序思路
    • 代码实现

堆是一颗完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子结点的值。

  • 大顶堆:父亲结点的值大于或等于孩子结点的值。
  • 小顶堆:父亲结点的值小于或等于孩子结点的值。

定义堆

  • 使用数组来存储完全二叉树,结点按层序存储于数组中,其中第一个结点将存储于数组中的1号位,并且数组 i 号位表示的结点的左孩子就是 2i 号位,而右孩子则是(2i+1)号位。
#define MaxSize 1000
// heap为堆,n为元素个数
int heap[MaxSize], n = 10;

建堆(以大顶堆为例)

对一个给定的初始序列,用向下调整的思路构建大顶堆:

  1. 总是将当前结点V与它的左右孩子比较(如果有的话)。
  2. 假如孩子中存在权值比结点V的权值大的,就将其中权值最大的那个孩子结点与结点V交换。
  3. 交换完毕后继续让结点V和孩子比较,直到结点V的孩子的权值都比结点V的权值小或是结点V不存在孩子结点。
void swap(int *a, int *b) {int t = *a;*a = *b;*b = t;
}// 对heap数组在[low,high]范围进行向下调整
// 其中low为欲调整结点的数组下标,high一般为堆的最后一个元素的数组下标
void downAdjust(int low, int high) {int i = low, j = i * 2;             // i为欲调整结点,j为其左孩子while (j <= high) {                 // 存在孩子结点// 如果右孩子存在,且右孩子的值大于左孩子if (j + 1 <= high && heap[j + 1] > heap[j])j = j + 1;      // 让j存储右孩子下标// 如果孩子中最大的权值比欲调整结点i大if (heap[j] > heap[i]) {swap(&heap[j], &heap[i]);   // 交换最大权值的孩子与欲调整结点i = j;                      // 保持i为欲调整结点j = i * 2;                  // j为i的左孩子} elsebreak;                      // 孩子的权值均比欲调整结点i小,则无需向下调整}
}
  • 假设序列中元素的个数为n,由于完全二叉树的叶子结点个数为ceiling(n/2),因此数组下标在[1,floor(n/2)]范围内的结点都是非叶子结点。
  • 从floor(n/2)号位开始倒着枚举结点,对每个遍历到的结点i进行[i,n]范围的调整
  • 这样每次调整完一个结点后,当前子树中权值最大的结点就会处在根结点的位置,保证了每个结点都是以其为根结点的子树中的权值最大的结点

建堆代码如下,时间复杂度为O(n)。

// 建堆
void createHeap() {for (int i = n / 2; i >= 1; --i)downAdjust(i, n);
}

删除堆顶元素

删除堆顶元素,即删除堆中最大的元素(大顶堆),并让其仍然保持堆的结构。

  • 用最后一个元素覆盖堆顶元素。
  • 对根结点进行向下调整。

代码如下,时间复杂度为O(logn)。

// 删除堆顶元素
void deleteTop() {heap[1] = heap[n--];                // 用最后一个元素覆盖堆顶元素,并让元素个数减1downAdjust(1, n);               	// 向下调整堆顶元素
}

插入元素

向堆中插入一个元素,并让其仍然保持堆的结构。

  • 把要插入的元素放在数组的最后(也就是完全二叉树的最后一个结点后面)。
  • 然后进行向上调整操作:把欲调整结点与父亲结点比较,如果权值比父亲结点大,那么就交换其与父亲结点
  • 这样反复比较,直到到达堆顶或是父亲结点的权值较大为止。
  • 向上调整的时间复杂度为O(logn)。

代码如下。

// 对heap数组在[low,high]范围进行向上调整
// 其中low一般设置为1,high表示欲调整结点的数组下标
void upAdjust(int low, int high) {int i = high, j = i / 2;            // i为欲调整结点,j为其父亲结点while (j >= low) {                  // 父亲结点在[low,high]范围内// 父亲权值小于欲调整结点i的权值if (heap[j] < heap[i]) {swap(&heap[j], &heap[i]);   // 交换父亲结点和欲调整结点i = j;                      // 保持i为欲调整结点j = i / 2;                  // 保持j为i的父亲} elsebreak;                      // 父亲的权值比欲调整结点i的权值大,调整结束}
}// 添加元素x
void insert(int x) {heap[++n] = x;                      // 让元素个数加1,然后将数组末位赋值为xupAdjust(1, n);                 	// 向上调整新加入的结点n
}

堆排序

堆排序是指使用堆结构对一个序列进行排序。此处讨论大顶堆递增排序的情况。

排序思路

  1. 大顶堆建堆完毕后,堆顶元素是最大的。
  2. 取出堆顶元素,将堆的最后一个元素替换至堆顶。
  3. 针对堆顶元素,进行一次向下调整的操作。
  4. 重复②③,直至堆中只剩一个元素。
  5. 注意:
    1. 大顶堆排序完后,heap数组中的元素为升序;
    2. 小顶堆排序完后,heap数组中的元素为降序;
    3. 升序建大顶堆,降序建小顶堆

代码实现

  1. 倒着遍历数组(节省空间),访问到i号位时,将堆顶元素和i号位的元素交换。
  2. 接着在[1,i - 1]范围内对堆顶元素进行一次向下调整即可。
// 堆排序
void heapSort() {createHeap();                       // 建堆for (int i = n; i > 1; --i) {       // 倒着枚举,直到堆中只有一个元素swap(&heap[i], &heap[1]);       // 交换heap[i]与堆顶downAdjust(1, i - 1);       	// 调整堆顶}
}

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

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

相关文章

jmeter之并发和顺序执行与特殊线程组-第四天

1.jmeter的并发执行 并发执行&#xff1a;多个线程同时执行&#xff0c;不能确定谁先结束 以上案例中http请求里面没有写任何内容&#xff0c;只是为了看这个并发执行的效果 2.jmeter的顺序执行 顺序执行&#xff1a;多个线程顺序执行 再测试计划中勾选“独立运行每个线程组…

VBA之Word应用:利用Bookmark属性返回选择区域的开始和结束位置

《VBA之Word应用》&#xff08;版权10178982&#xff09;&#xff0c;是我推出第八套教程&#xff0c;教程是专门讲解VBA在Word中的应用&#xff0c;围绕“面向对象编程”讲解&#xff0c;首先让大家认识Word中VBA的对象&#xff0c;以及对象的属性、方法&#xff0c;然后通过实…

什么是子网掩码、ip地址的网段?如何区分?

IP地址优化网写了很多相关的文章。 有些朋友对于子网掩码、IP地址网段等还不太了解&#xff0c;我们来看看网友经常问到的一些相关问题。 255.255.255.192 的位掩码是什么&#xff1f; 1.什么是子网掩码&#xff1f; 在了解IP地址的网段之前&#xff0c;我们先来了解一下子网…

在sql server 2016 always on集群里新增一个数据库节点

本篇博客有对应的word版本&#xff0c;有需要的可以点击这里下载。 一 环境介绍 二 操作步骤 2.1 在新节点上安装sql server软件 略 2.2 在新节点上开启‘故障转移群集功能’ 打开‘服务管理器’&#xff1a; 点击‘添加角色和功能’&#xff1a; 勾选’DNS服务器’&#…

Mybatis和Mybatis-Plus面试题

一、MyBatis是什么&#xff1f; MyBatis 是一款开源的、轻量级的对象关系映射&#xff08;ORM&#xff09;框架&#xff0c;用于Java应用中的数据库持久层操作。它简化了与数据库之间的交互&#xff0c;让开发者可以更专注于编写SQL语句和关注业务逻辑&#xff0c;而不需要处理…

Figure AI的6.75亿美元突破性进展在类人机器人领域

人形机器人领域的重大突破&#xff1a;Figure AI获得6.75亿美元投资 在技术不断发展的今天&#xff0c;人形机器人领域正逐渐成为前沿技术之一&#xff0c;充满了无限的可能性和希望。这一概念&#xff0c;曾经只存在于科幻小说中&#xff0c;如今正迅速成为现实&#xff0c;这…

QT配置libtorch(一步到位!!!防止踩坑)

QT配置libtorch Qt下载QT配置MSVCQT配置Libtorch Qt下载 Qt点击下载 Qt的安装选择MSVC2017 64-bit(一定要安装&#xff0c;这关乎后面的配置&#xff01;&#xff01;&#xff01;)&#xff0c;其他的根据自己的选择进行安装 QT配置MSVC Visual Studio点击安装 这里需要安装VS以…

元宇宙VR数字化艺术展降低办展成本

元宇宙AI时代已经来临&#xff0c;越来越多人期待在元宇宙数字空间搭建一个属于自己的虚拟展厅&#xff0c;元宇宙虚拟展厅搭建平台是VR公司深圳华锐视点为企业研发的可编辑工具&#xff0c;那么元宇宙虚拟展厅搭建平台有哪些新突破? 元宇宙虚拟展厅搭建平台采用了先进的web3D…

(一)基于IDEA的JAVA基础2

通过记事本练习我们可以大致了解java的运行过程 使用工具开发: 常用工具:Eclipse, MyEclipse,IDEA 这里我们用的开发工具是IDEA&#xff0c;其下载和破解方式在我们这个平台上一搜就有&#xff0c;这个我就不多言了&#xff0c;其他老师都比我有权威性&#xff0c;因为我当初…

统计学基础概念和在AI中的应用

基本概念 统计学是一门研究数据收集、分析、解释和展示的科学&#xff0c;它提供了一套方法论&#xff0c;用于理解数据并从数据中得出结论。统计学在各个领域都有应用&#xff0c;包括经济学、医学、工程学、社会科学等。以下是统计学的一些基本概念&#xff1a; 描述性统计…

文件上传基础篇

文件上传基础篇 文件上传漏洞原理 ​ 目标网站存在文件上传接口&#xff0c;但是对用户上传的文件没有做仔细甄别&#xff0c;导致黑客可以根据此功能点直接上传木马到网站服务器&#xff0c;造成危害 文件上传存在点 ​ 通常有头像上传&#xff0c;pdf上传 文件上传防护 …

使用verilog编写记忆拼图游戏设计及仿真

游戏设计思路: 编写记忆拼图游戏的Verilog设计涉及到多个部分,包括状态机设计、随机数生成、按钮输入检测、LED显示控制等。以下是实现记忆拼图游戏设计的一般思路: 状态机设计: 定义游戏所需的状态,如空闲状态(IDLE)、展示图案状态(SHOW_PATTERN)、猜测图案状态(GUE…

【数据结构和算法初阶(C语言)】二叉树的顺序结构--堆的实现/堆排序/topk问题详解---二叉树学习日记②1

目录 ​编辑 1.二叉树的顺序结构及实现 1.1 二叉树的顺序结构 2 堆的概念及结构 3 堆的实现 3.1堆的代码定义 3.2堆插入数据 3.3打印堆数据 3.4堆的数据的删除 3.5获取根部数据 3.6判断堆是否为空 3.7 堆的销毁 4.建堆以及堆排序 4.1堆排序---是一种选择排序 4.2升序建大堆&a…

(二)ffmpeg的相关命令,以及JAVA操作ffmpeg

一、常用查看指令 1.查看FFmpeg支持的编码器 ffmpeg configure -encoders2.查看FFmpeg支持的编码器 ffmpeg configure -decoders3.查看ffmpeg支持的通信协议 ffmpeg configure -protocols4.查看FFmpeg所支持的音视频编码格式、文件封装格式与流媒体传输协议 ffmpeg configure …

鸿蒙实战开发:【浏览器制作】

浏览器 介绍 本示例使用[ohos.systemparameter]接口和[Web组件]展示了一个浏览器的基本功能,展示网页&#xff0c;根据页面历史栈前进回退等。 效果预览 首页打开网址 使用说明: 连接Wifi&#xff0c;启动应用&#xff0c;展示默认页面内容;点击默认页面的图标跳转到对应…

C语言经典算法-7

文章目录 其他经典例题跳转链接36.排序法 - 改良的选择排序37.快速排序法&#xff08;一&#xff09;38.快速排序法&#xff08;二&#xff09;39.快速排序法&#xff08;三&#xff09;40.合并排序法 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三…

AnyGo for Mac最新激活版:位置模拟软件打破地域限制

AnyGo for Mac&#xff0c;一款专为Mac用户打造的位置模拟软件&#xff0c;让您能够轻松打破地域限制&#xff0c;畅享无限可能。 软件下载&#xff1a;AnyGo for Mac v7.0.0最新激活版 通过AnyGo&#xff0c;您可以随时随地模拟出任何地理位置&#xff0c;无论是国内热门景点还…

(三)pulsar可视化消息管理工具

官网&#xff1a;https://pulsar.apache.org/docs/3.2.x/administration-pulsar-manager/ 版本: 3.2.x 安装和配置 拉取容器 docker pull apachepulsar/pulsar-manager:v0.3.0运行容器&#xff1a; # pulsar消息管理工具 CURRENT_DIR$(cd dirname $0; pwd) BASE_DIR$(cd $(…

【07】进阶html5

HTML5 包含两个部分的更新,分别是文档和web api 文档 HTML5 元素表 元素语义化 元素语义化是指每个 HTML 元素都代表着某种含义,在开发中应该根据元素含义选择元素 元素语义化的好处: 利于 SEO(搜索引擎优化)利于无障碍访问利于浏览器的插件分析网页新增元素 多媒体…

手撕算法-判断是不是完全二叉树

描述&#xff1a;思路&#xff1a;采用层序遍历&#xff0c;找到一个为空的标记&#xff0c;如果后面还有值&#xff0c;就代表不是完全二叉树。代码&#xff1a; public boolean isCompleteTree (TreeNode root) {// write code hereif(root null) return true;Queue<Tree…