当前位置: 首页 > news >正文

【数据结构】--- 堆的应用

 

 个人主页:星纭-CSDN博客

系列文章专栏 :数据结构

踏上取经路,比抵达灵山更重要!一起努力一起进步!

一.堆排序 

 在前一个文章的学习中,我们使用数组的物理结构构造出了逻辑结构上的堆。那么堆到底有什么用呢???

首先思考这样一个问题,假设给定一个随机的数组,如何将这个数组建堆(在不使用额外的空间的条件下)。

这个问题不难,只需用到向上调整算法即可。

int main()
{int a[] = { 4,2,8,1,5,6,9,7,3,2,23,55,232,66,222,33,7,1,66,3333,999 };int i = 1;for (i = 1; i < sizeof(a) / sizeof(a[0]); i++) {AdjustUp(a, i);}return 0;
}

通过调试不难发现此时已经是一个大堆了。

如果想要得到小堆,只需要更改向上调整函数即可。

得到了大堆之后,又如何将这个数组排序得到一个升序的数组呢???

因为在大堆中,堆顶的数据一定是最大的,可以先将堆顶数据和数组最后一个位置上的数据进行交换,不管此时最大的数据,只看前size-1这个数据,进行向下调整得到第二大的数据,再更倒数第二个位置上的数据进行交换,..........依次进行下去就会得到一个升序的数组。 

int main()
{int a[] = { 4,2,8,1,5,6,9,7,3,2,23,55,232,66,222,33,7,1,66,3333,999 };int i = 1;for (i = 1; i < sizeof(a) / sizeof(a[0]); i++) {AdjustUp(a, i);}int end = sizeof(a) / sizeof(a[0]) - 1;while (end > 0) {Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;}return 0;
}

简单来说,升序,建大堆,降序,建小堆。这就是堆排序。

然后就是向下调整建堆。假设给定一个数组,使用二叉树的形式表示,如下图所示 

假设这个二叉树,对于根来说,其左子树是大堆,右子树也是大堆,而这整个二叉树并不是大堆,我们就可以使用向下调整来使其变成大堆。可是这样一个随机的数组肯定是不满足上述的条件的,那么该如何使用向下调整算法来使其变成大堆呢?

答案就是倒着调整。

假设我们从最后一个数据开始,一个节点是既可以看作大堆也可以看作小堆的,此时我们就不需要对其进行调整,对于完全二叉树来说,他的叶子节点都不需要调整,所以我们就需要调整倒数第一个非叶子节点。以上图举例,也就是第三层第二个节点,将它和它的孩子节点看作一个树,这样就可以调整了。

那么倒数第一个非叶子节点的下标该怎么求呢?

倒数第一个非叶子节点是最后一个节点父亲节点。而最后一个节点的下标是n-1。所以倒数第一个非叶子节点的下标就是(n-1-1)/ 2;

	for (int i = (n-1-1)/2; i >= 0; i--){AdjustDown(a, n, i);}

二.建堆的时间复杂度

既然有两种不同的建堆算法,那么采用哪一种算法来建堆是更加好的呢?

所以接下来算一算两个算法的时间复杂度 

对于一个完全二叉树而言,假设其高度是h,那么它的节点个数最少和最多情情况,分别是最后一层只有一个节点和一个满二叉树。

对于一个满二叉树来说总节点个数n和高度h的关系是

F(n) = 2^0 + 2^1 + 2^2 + ... + 2^(h-1) = 2^h - 1。

h = log2(n + 1)

对于最后一层只有一个节点的二叉树而言总节点个数和高度h的关系是

F(n) = 2^0 + 2^1 + 2^2 + ... + 2^(h-2) + 1 = 2^(h-1) - 1 + 1= 2^(h-1)。

h = log2(n) - 1

根据大O的渐进表示法,我们可以大致得到h = logN的。

这样我们就得到了h和N之间的关系。

1.向上调整

计算向上调整的时间复杂度,我们需要计算总共向上调整了几次。

T(h) = 2^1*1 + 2^2 * 2 + ... + 2^(h-2)*(h-2) + 2^(h-1)*(h-1).
2*T(h) =       2^2*1 + 2^3 * 2 + ... +         2^(h-1)*(h-2) + 2^h*(h-1).
-T(h) = 2^1 + 2^2 + ... +2^(h-1) - 2^h*(h-1).= 2^h  - 2 -2^h*(h-1)= 2^h(1-h+1) -2 T(h) = 2 + 2 ^ h * hT(N) = 2 + 2 * log(N) * N = O(N * logN)

向上调整的时间复杂度是N*logN.

2.向下调整

T(h) = 2^0*(h-1) + 2^1*(h-2) + ...             +2^(h-2) * 1
2 * T(h) =         2^1*(h-1) + 2^2*(h-2) + ... +2^(h-2) * 2+2^(h-1) * 1
T(h) = 2^1 + 2^2+...+2^(h-2) +2^(h-1) - (h-1)= 2^h - 2 - h + 1= 2^h - h - 1= N - logN - 1= O(N)

对比不难发现向下调整的时间复杂度算法更优。 

三.TopK问题

 TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。
    比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。
对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能
数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,基本思路如下:
1. 用数据集合中前K个元素来建堆
    前k个最大的元素,则建小堆
    前k个最小的元素,则建大堆
2. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素    
将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

利用此算法的时间复杂度是O(N)

 

相关文章:

【数据结构】--- 堆的应用

​ 个人主页&#xff1a;星纭-CSDN博客 系列文章专栏 :数据结构 踏上取经路&#xff0c;比抵达灵山更重要&#xff01;一起努力一起进步&#xff01; 一.堆排序 在前一个文章的学习中&#xff0c;我们使用数组的物理结构构造出了逻辑结构上的堆。那么堆到底有什么用呢&…...

0基础学会在亚马逊云科技AWS上利用SageMaker、PEFT和LoRA高效微调AI大语言模型(含具体教程和代码)

项目简介&#xff1a; 小李哥今天将继续介绍亚马逊云科技AWS云计算平台上的前沿前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS上的AI软甲开发最佳实践&#xff0c;并应用到自己的日常工作里。本次介绍的是如何在Amazon SageMaker上…...

护网HW面试——redis利用方式即复现

参考&#xff1a;https://xz.aliyun.com/t/13071 面试中经常会问到ssrf的打法&#xff0c;讲到ssrf那么就会讲到配合打内网的redis&#xff0c;本篇就介绍redis的打法。 未授权 原理&#xff1a; Redis默认情况下&#xff0c;会绑定在0.0.0.0:6379&#xff0c;如果没有采用相关…...

C++ //练习 15.8 给出静态类型和动态类型的定义。

C Primer&#xff08;第5版&#xff09; 练习 15.8 练习 15.8 给出静态类型和动态类型的定义。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 解释 静态类型&#xff1a;在编译时已知&#xff0c;是在变量声明时的类型或表达式生成的…...

阿里云ECS服务器安装jdk并运行jar包,访问成功详解

安装 OpenJDK 8 使用 yum 包管理器安装 OpenJDK 8 sudo yum install -y java-1.8.0-openjdk-devel 验证安装 安装完成后&#xff0c;验证 JDK 是否安装成功&#xff1a; java -version设置 JAVA_HOME 环境变量&#xff1a; 为了确保系统中的其他应用程序可以找到 JDK&…...

Windows系统上使用npm来安装和配置Yarn,在VSCode中使用

一、安装Yarn 1. 安装Node.js和npm 如果还没有安装Node.js和npm&#xff0c;可以从Node.js官方网站下载并安装最新版本的Node.js&#xff0c;npm会随Node.js一起安装。 2. 使用npm安装Yarn 打开命令提示符或PowerShell&#xff0c;运行以下命令来全局安装Yarn&#xff1a; …...

Unity ColorSpace 之 【颜色空间】相关说明,以及【Linear】颜色校正 【Gamma】的简单整理

Unity ColorSpace 之 【颜色空间】相关说明&#xff0c;以及【Linear】颜色校正 【Gamma】的简单整理 目录 Unity ColorSpace 之 【颜色空间】相关说明&#xff0c;以及【Linear】颜色校正 【Gamma】的简单整理 一、简单介绍 二、在Unity中设置颜色空间 三、Unity中的Gamma…...

JavaScript的学习(二)

今天继续学习JavaScript的第二天&#xff0c;还是打基础 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title…...

【接口自动化_06课_Pytest+Excel+Allure完整框架集成】

一、logging在接口自动化里的应用 1、设置日志的配置&#xff0c;并收集日志文件 日志的设置需要在pytest.ini文件里设置。这个里面尽量不要有中文 2、debug日志的打印 pytest.ini文件的开关一定得是true才能在控制台打印日志 import allure import pytest from P06_PytestFr…...

Profibus协议转Profinet协议网关模块连接智能电表通讯案例

一、背景 在工业自动化领域&#xff0c;Profibus协议和Profinet协议是两种常见的工业通讯协议&#xff0c;而连接智能电表需要用到这两种协议之间的网关模块。本文将通过一个实际案例&#xff0c;详细介绍如何使用Profibus转Profinet模块&#xff08;XD-PNPBM20&#xff09;实…...

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(九)-无人机服务区分离

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…...

acrobat 中 PDF 复制时不能精确选中所选内容所在行的一种解决方法

现象&#xff1a;划取行的时候&#xff0c;自动扩展为多行 如果整段选中复制&#xff0c;粘贴后是乱码 解决步骤 识别完&#xff0c;保存 验证 可以按行复制了。 如果遇到仅使用 acrobat OCR 不能彻底解决的&#xff0c;更换其他自己熟悉的进行 OCR。...

安卓学习中遇到的问题【bug】

安卓学习中遇到的问题 1Gradle下载慢怎么办&#xff1f; Gradle下载慢怎么办&#xff1f; distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-7.5-bin.zip 2 Could not resolve all files for configuration ‘:classpath‘. &#xff1e; Could not resolv…...

【日常记录】【CSS】display:inline 的样式截断

文章目录 1. 案例2. css属性&#xff1a;box-decoration-break参考地址 1. 案例 现在有一篇文章&#xff0c;某些句子&#xff0c;是要被标记的&#xff0c;加一些css 让他突出一下 可以看到&#xff0c;在最后&#xff0c;断开了&#xff0c;那如若要让 断开哪里的样式 和 开始…...

数据库系统安全

数据库安全威胁 数据库作为信息系统中的核心组成部分&#xff0c;存储和管理着大量敏感和关键的数据&#xff0c;成为网络攻击者的主要目标之一。以下是常见的数据库安全威胁及其详细描述&#xff1a; 一、常见数据库安全威胁 SQL注入攻击&#xff08;SQL Injection&#xff…...

Qt MV架构-代理模型

一、基本概念 代理模型可以将一个模型中的数据进行排序或者过滤&#xff0c;然后提供给视图进行显示。 Qt中提供了QSortFilterProxyModel作为标准的代理模型来完成模型中数据的排序和过滤。 要使用一个代理模型&#xff0c;则只需要为其设置源模型&#xff0c;然后再视图中使…...

WebSocket实现群聊功能、房间隔离

引用WebSocket相关依赖 <dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.1</version></dependency><dependency><groupId>org.springframework</grou…...

顶顶通呼叫中心中间件实现随时启动和停止质检(mod_cti基于FreeSWITCH)

文章目录 前言联系我们拨号方案启动停止ASR执行FreeSWITCH 命令接口启动ASR接口停止ASR接口 通知配置cti.json配置质检结果写入数据库 前言 顶顶通呼叫中心中间件的实时质检功能是由两个模块组成&#xff1a;mod_asr 和 mod_qc。 mod_asr&#xff1a;负责调用ASR将用户们在通…...

基于conda包的环境创建、激活、管理与删除

Anaconda是一个免费、易于安装的包管理器、环境管理器和 Python 发行版&#xff0c;支持平台包括Windows、macOS 和 Linux。下载安装地址&#xff1a;Download Anaconda Distribution | Anaconda 很多不同的项目可能需要使用不同的环境。例如某个项目需要使用pytorch1.6&#x…...

处理线程安全的列表CopyOnWriteArrayList 和Collections.synchronizedList

ConcurrentModificationException 是 Java 中的一种异常&#xff0c;用于指示在迭代集合时&#xff0c;该集合的结构发生了并发修改。 在 Java 中&#xff0c;许多集合类&#xff08;如 ArrayList, HashMap 等&#xff09;都不是线程安全的。如果一个线程在迭代集合的同时&…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...