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

【数据结构】核心数据结构之二叉堆的原理及实现

1.大顶堆和小顶堆原理

  • 什么是堆

    • 堆(Heap)是计算机科学中一类特殊的数据结构,通常是一个可以被看作一颗完全二叉树的数组对象。

    • 完全二叉树

      • 只有最下面两层节点的度可以小于2,并且最下层的叶节点集中在靠左连续的边界

      • 只允许最后一层有空缺结点且空缺在右边,完全二叉树需保证最后一个节点之前的节点都齐全;

      • 对任一结点,如果其右子树的深度为j,则其左子树的深度必为j或j+1

在这里插入图片描述

  • 什么是大顶堆(最大堆)
    • 大顶堆是一种完全二叉树,其每个父节点的值都大于或等于其子节点的值,即根节点的值最大。
    • 每个节点的两个子节点顺序没做要求,和之前的二叉查找树不一样。

在这里插入图片描述

  • 什么是小顶堆(最小堆)

    • 小顶堆是一种完全二叉树,其每个父节点的值都小于或等于其子节点的值,即根节点的值最小。

    • 每个节点的两个子节点顺序没做要求,和之前的二叉查找树不一样

在这里插入图片描述

  • 存储原理

    • 一般升序采用大顶堆,降序采用小顶堆。
    • 堆是一种非线性结构,用数组来存储完全二叉树是非常节省空间的,把堆看作一个数组。
      • 方便操作,一般数组的下标0不存储,直接从1节点存储。
    • 堆其实就是利用完全二叉树的结构来维护一个数组
    • 数据下表为k的节点
      • 左子节点下标为2*k的节点。
      • 右子节点就是下表为2*k+1的节点。
      • 父节点就是下标为k/2取证的节点。
  • 公式描述一下堆的定义

    • 大顶堆:arr[k] >= arr[2k+1] && arr[k] >= arr[2k]
    • 小顶堆:arr[k] <= arr[2k+1] && arr[k] <=arr[ak]
  • 小顶堆动画效果演示

  • 往堆中插入新元素,就是往数组中从索引0或1开始依次存放数据,但是顺序需要满足堆的特性

  • 如何让堆满足:
    • 不断比较新节点 arr[k]和对应父节点arr[k/2]的大小,根据情况交互元素位置
    • 直到找到的父节点比当前新增节点大则结束

在这里插入图片描述

2.大顶堆构编码实现

  • 大顶堆(最大堆)

    • 大顶堆是一种完全二叉树,其每个父节点的值都大于或等于其子节点的值,即根节点的值最大

在这里插入图片描述

  • 编码实现
public class Heap {//用数组存储堆中的元素private int[] items;//堆中元素的个数private int num;public Heap(int capacity) {//数组下标0不存储数据,所以容量+1this.items = new int[capacity + 1];this.num = 0;}/*** 判断堆中 items[left] 元素是否小于 items[right] 的元素*/private boolean rightBig(int left, int right) {return items[left] < items[right];}/*** 交换堆中的两个元素位置*/private void swap(int i, int j) {int temp = items[i];items[i] = items[j];items[j] = temp;}/*** 往堆中插入一个元素,默认是最后面,++num先执行,然后进行上浮判断操作*/public void insert(int value) {items[++num] = value;up(num);}/*** 使用上浮操作,新增元素后,重新堆化* 不断比较新节点 arr[k]和对应父节点arr[k/2]的大小,根据情况交互元素位置* 直到找到的父节点比当前新增节点大则结束* <p>* 数组中下标为 k 的节点* 左子节点下标为 2*k 的节点* 右子节点就是下标 为 2*k+1 的节点* 父节点就是下标为 k/2 取整的节点*/private void up(int k) {//父节点 在数组的下标是1,下标大于1都要比较while (k > 1) {//比较 父结点 和 当前结点 大小if (rightBig(k / 2, k)) {//当前节点大,则和父节点交互位置swap(k / 2, k);}// 往上一层比较,当前节点变为父节点k = k / 2;}}/*** 删除堆中最大的元素,返回这个最大元素*/public int delMax() {int max = items[1];//交换索引 堆顶的元素(数组索引1的)和 最大索引处的元素,放到完全二叉树中最右侧的元素,方便后续变为临时根结点// 为啥不能直接删除顶部元素,因为删除后会断裂,成为森林,所以需要先交互,再删除swap(1, num);//最大索引处的元素删除掉, num--是后执行,元素个数需要减少1items[num--] = 0;//通过下浮调整堆,重新堆化down(1);return max;}/*** 使用下沉操作,堆顶和最后一个元素交换后,重新堆化* 不断比较 节点 arr[k]和对应 左节点arr[2*k] 和 右节点arr[2*k+1]的大小,如果当前结点小,则需要交换位置* 直到找到 最后一个索引节点比较完成  则结束* 数组中下标为 k 的节点* 左子节点下标为 2*k 的节点* 右子节点就是下标 为 2*k+1 的节点* 父节点就是下标为 k/2 取整的节点*/private void down(int k) {//最后一个节点下标是numwhile (2 * k <= num) {//记录当前结点的左右子结点中,较大的结点int maxIndex;if (2 * k + 1 <= num) { //2 * k + 1 <= num 是判断 确保有右节点//比较当前结点下的左右子节点哪个大if (rightBig(2 * k, 2 * k + 1)) {maxIndex = 2 * k + 1;} else {maxIndex = 2 * k;}} else {maxIndex = 2 * k;}//比较当前结点 和 较大结点的值, 如果当前节点较大则结束if (items[k] > items[maxIndex]) {break;} else {//否则往下一层比较,当前节点k索引 变换为 子节点中较大的值swap(k, maxIndex);//变换k的值k = maxIndex;}}}public static void main(String[] args) {Heap heap = new Heap(20);heap.insert(42);heap.insert(48);heap.insert(93);heap.insert(21);heap.insert(90);heap.insert(9);heap.insert(3);heap.insert(40);heap.insert(32);int top;System.out.println("输出堆:");while ((top = heap.delMax()) != 0) {System.out.print(top + " ");}}
}

在这里插入图片描述

相关文章:

【数据结构】核心数据结构之二叉堆的原理及实现

1.大顶堆和小顶堆原理 什么是堆 堆&#xff08;Heap&#xff09;是计算机科学中一类特殊的数据结构&#xff0c;通常是一个可以被看作一颗完全二叉树的数组对象。 完全二叉树 只有最下面两层节点的度可以小于2&#xff0c;并且最下层的叶节点集中在靠左连续的边界 只允许最后…...

Spring Cloud Alibaba+saas企业架构技术选型+架构全景业务图 + 架构典型部署方案

基于Spring Cloud Alibaba 分布式微服务高并发数据平台化(中台)思想多租户saas设计的企业开发架构&#xff0c;支持源码二次开发、支持其他业务系统集成、集中式应用权限管理、支持拓展其他任意子项目。 一、架构技术选型 核心框架 Spring Boot SOA Spring Cloud …...

RocketMQ-03

1. 高级功能 1.1 消息存储 分布式队列因为有高可靠性的要求&#xff0c;所以数据要进行持久化存储。 消息生成者发送消息MQ收到消息&#xff0c;将消息进行持久化&#xff0c;在存储中新增一条记录返回ACK给生产者MQ push 消息给对应的消费者&#xff0c;然后等待消费者返回A…...

大神教你在 Linux 中查看你的时区

在这篇短文中&#xff0c;我们将向你简单介绍几种 Linux 下查看系统时区的简单方法。在 Linux 机器中&#xff0c;尤其是生产服务器上的时间管理技能&#xff0c;是在系统管理中一个极其重要的方面。Linux 包含多种可用的时间管理工具&#xff0c;比如 date 或 timedatectlcomm…...

Redis持久化策略

Redis有两种持久化方式:快照(snapshotting,或者叫Redis DataBase,RDB)和只追加文件(append-only,AOF)。两种方式可以单独使用,也可以同时使用。 1.RDB模式 RDB:将某时刻所有数据都写入到硬盘里,存储为.rdb快照文件,新的快照文件生成之后会替换旧的快照文件。用户可以将…...

显著性检验【t-test、方差分析、ks检验】

显著性检验【t-test、方差分析、ks检验】 0、目录 1显著性检验基本定义&#xff08;what&#xff1f;&#xff09; 2.使用显著性检验的意义&#xff08;why? &#xff09; 3.显著性检验的具体操作流程&#xff08;how? &#xff09; 1、显著性检验基本定义 统计假设检验…...

访问学者在德国访学生活衣食住行攻略

德国因其优质的教育水平、高价值的学制、低廉的访学成本&#xff0c;逐渐成为访学领域的宠儿。对于初次来到德国生活的访问学者&#xff0c;一定不是很熟悉德国的真实生活情况。今天51访学网小编就给大家介绍德国访学学衣食住行&#xff0c;希望可以帮助到即将出国的你。 一、…...

SQL-刷题技巧-删除重复记录

一. 原题呈现 牛客 SQL236. 删除emp_no重复的记录&#xff0c;只保留最小的id对应的记录。 描述&#xff1a; 删除emp_no重复的记录&#xff0c;只保留最小的id对应的记录。 drop table if exists titles_test; CREATE TABLE titles_test (id int(11) not null primary key…...

基于JSP的虚拟账号交易平台

技术&#xff1a;Java、JSP等摘要&#xff1a;随着网络游戏以及各种平台的出现与更新&#xff0c;虚拟账号交易平台正逐渐成为电商的新增长点。当今社会&#xff0c;互联网发发展飞速&#xff0c;游戏产业也渐渐兴起&#xff0c;随之虚拟游戏账号的交易量逐渐增多&#xff0c;但…...

LeetCode201_201. 数字范围按位与

LeetCode201_201. 数字范围按位与 一、描述 给你两个整数 left 和 right &#xff0c;表示区间 [left, right] &#xff0c;返回此区间内所有数字 按位与 的结果&#xff08;包含 left 、right 端点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;left 5, right 7 输…...

一款好的风险管理软件可以做什么

风险管理软件哪个好&#xff1f;使用Zoho Projects易于使用的项目风险管理软件&#xff0c;最大限度地减少收入损失并快速调整您的投资组合&#xff0c;保护您的项目投资。Zoho Projects的高级风险管理软件可在您最需要的时候安全的保护您的业务。使用Zoho Projects强大的风险管…...

html2canvas使用文档

一、安装 Install NPM npm install --save html2canvasInstall Yarn yarn add html2canvas二、引入 import html2canvas from html2canvas;三、使用 以 vue 举例&#xff0c;这样写起来比较方便 <div ref"picture"><h4>Hello world!</h4> &l…...

HTML DOM 改变 CSS

HTML DOM 允许 JavaScript 改变 HTML 元素的样式。改变 HTML 样式如需改变 HTML 元素的样式&#xff0c;请使用这个语法&#xff1a;document.getElementById(id).style.propertynew style 下面的例子会改变 <p> 元素的样式&#xff1a;实例<html><body><…...

基于EB工具的TC3xx_MCAL配置开发01_WDG模块配置介绍

目录 1.概述2. WDG 配置2.1 General部分配置2.2 WdgSettingsConfig配置2.2.1 配置概述2.2.2 CPU WDG具体配置2.3 WdgDemEventParameterRefs3. WDG配置注意事项1.概述 本篇开始我们基于EB Tresos工具对英飞凌TC3xx系列MCU的MCAL开发进行介绍,结合项目经验对各MCAL外设的开发及…...

Activty启动到显示的过程[二]

Activity的显示从handleResumeActivity()方法开始。 //ActivityThread.javaOverridepublic void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,String reason) {final ActivityClientRecord r performResumeActivity(token, finalStat…...

ubuntu 18.04.06LST安装R4.0+版本报错及解决过程

1. sudo apt-get update无法正常使用 错误:13 http://ppa.launchpad.net/webupd8team/sublime-text-3/ubuntu bionic Release 404 Not Found [IP: 2620:2d:4000:1::3e 80] 解决措施&#xff1a;删除 webupd8team/sublime-text-3这个ppa文件。 sudo add-apt-repository --…...

数据湖架构Hudi(五)Hudi集成Flink案例详解

五、Hudi集成Flink案例详解 5.1 hudi集成flink flink的下载地址&#xff1a; https://archive.apache.org/dist/flink/ HudiSupported Flink version0.12.x1.15.x、1.14.x、1.13.x0.11.x1.14.x、1.13.x0.10.x1.13.x0.9.01.12.2 将上述编译好的安装包拷贝到flink下的jars目录…...

【Java学习笔记】9.Java 循环结构 - for, while 及 do...while

Java 循环结构 - for, while 及 do…while 顺序结构的程序语句只能被执行一次。 如果您想要同样的操作执行多次&#xff0c;就需要使用循环结构。 Java中有三种主要的循环结构&#xff1a; while 循环do…while 循环for 循环 在 Java5 中引入了一种主要用于数组的增强型 f…...

【面向对象初步】之面向对象VS面向过程

面向对象(ObjectorientedProgramming,OOP)编程的思想主要是针对大型软件设计而来的。面向对象编程使程序的扩展性更强、可读性更好,使的编程可以像搭积木一样简单。 面向对象编程将数据和操作数据相关的方法封装到对象中,组织代码和数据的方式更加接近人的思维,从而大大提…...

原型链(回顾)

概念prototype__proto__原型链查找机制万物皆对象判断私有/共有属性方法Object.prototype.prototype nullObject.create(proto, [propertiesObject])给类的原型上扩展属性方法的4种方法Fn.prototype.xxx xxxObject.prototype.xxx xxxf1.proto.xxx xxx原型重定向 概念 原型…...

Python 3.14.5 发布:多项改进,垃圾回收器回滚,还有这些新特性!

Python 3.14.5 发布Python 3.14.5 现已发布&#xff0c;这是 3.14 的第五个维护版本。自 3.14.4 以来&#xff0c;包含约 154 项错误修复、构建改进和文档更改。垃圾回收器回滚值得注意的是&#xff0c;Python 3.14.5 中的垃圾回收器 (GC) 发生了变化。由于一些原因&#xff0c…...

终极指南:5分钟让Illustrator批量替换效率提升10倍

终极指南&#xff1a;5分钟让Illustrator批量替换效率提升10倍 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 还在为Adobe Illustrator中繁琐的批量替换工作而烦恼吗&#xff1f;&…...

嵌入式调试进阶:JScope RTT模式移植与性能实测(对比HSS,速度提升千倍)

嵌入式调试革命&#xff1a;JScope RTT模式深度优化与高频数据采集实战 在电机控制、电源管理和高速信号处理等嵌入式应用场景中&#xff0c;开发人员经常需要实时监控关键变量的变化趋势。传统调试工具往往面临采样率低、数据延迟大等问题&#xff0c;而SEGGER JScope的RTT模式…...

人工智能-现代方法(一)

2026.05.12 这几天开始看《人工智能-现代方法》&#xff0c;做一些知识记录。 1、学习的概念&#xff1a;归纳和演绎。&#xff08;19章&#xff09; 演绎靠逻辑推理&#xff0c;归纳靠经验总结。所以在前提正确的情况下&#xff0c;演绎的结论必然正确。归纳的结论则有可能出现…...

2025年英雄联盟国服内存级换肤技术深度解析:R3nzSkin架构设计与实现

2025年英雄联盟国服内存级换肤技术深度解析&#xff1a;R3nzSkin架构设计与实现 【免费下载链接】R3nzSkin-For-China-Server Skin changer for League of Legends (LOL) 项目地址: https://gitcode.com/gh_mirrors/r3/R3nzSkin-For-China-Server 你是否曾想过&#xff…...

别让直觉带路:Infoseek视角下的噪音过滤与火情预警实战

在舆情的世界里&#xff0c;最可怕的不是对手太强大&#xff0c;而是自己吓自己。很多时候&#xff0c;企业之所以“翻车”&#xff0c;并非因为危机本身不可控&#xff0c;而是因为公关团队在面对网友吐槽时过度敏感&#xff0c;发布了不必要的声明或做出了过激反应&#xff0…...

如何安全导出浏览器Cookie:本地化工具的完整使用教程

如何安全导出浏览器Cookie&#xff1a;本地化工具的完整使用教程 【免费下载链接】Get-cookies.txt-LOCALLY Get cookies.txt, NEVER send information outside. 项目地址: https://gitcode.com/gh_mirrors/ge/Get-cookies.txt-LOCALLY 你是否曾需要将浏览器Cookie导出到…...

如何在Dev-C++中配置TDM-GCC编译器

在Dev-C中配置TDM-GCC编译器的步骤如下&#xff1a; 步骤1&#xff1a;下载TDM-GCC编译器 访问 TDM-GCC官网下载适用于Windows的安装包&#xff08;推荐选择64位版本&#xff1a;tdm-gcc-xxx.exe&#xff09; 步骤2&#xff1a;安装TDM-GCC 运行安装程序&#xff0c;选择默认…...

基于Tauri框架构建轻量级ChatGPT桌面客户端:从原理到实践

1. 项目概述&#xff1a;一个基于Tauri的ChatGPT桌面客户端 最近在折腾AI应用本地化部署的时候&#xff0c;发现了一个挺有意思的项目&#xff1a; pljhonglu/ChatGPT-T 。这是一个用Tauri框架开发的ChatGPT桌面客户端&#xff0c;它的前端界面直接复用了开源项目 chatgpt-…...

Java基础全套教程(三)—— 控制语句、方法、递归算法

Java基础全套教程&#xff08;三&#xff09;—— 控制语句、方法、递归算法 本章是Java编程从基础语法走向逻辑编程的核心转折点。前面我们学习了变量、数据类型、运算符&#xff0c;只能实现简单的顺序执行代码。而真正的程序&#xff0c;需要具备判断能力、重复执行能力、代…...