基础数据结构 -- 堆

1. 简介

        堆可以看做是一种特殊的完全二叉树,它满足任意节点的值都大于或小于其子节点的值。

2. 功能

  • 插入元素:插入新元素时,先将元素放至数组末尾,然后通过上浮算法自底向上调整,使堆保持性质。
  • 删除堆顶元素:删除堆顶元素后,将最后一个元素移至堆顶,然后通过下沉算法自顶向下调整,重新满足堆的性质。
  • 建堆过程:从倒数第一个非叶子节点开始,对每个子树进行向下调整,直至整棵树满足堆的性质。

3. 图解

堆结构:

插入元素:

删除堆顶元素:

4. 实现

        在Java中,堆通常通过数组实现,利用数组的索引来表示节点之间的关系。

具体实现方式如下:

  • 定义一个数组来存储堆的元素。
  • 使用数组下标表示节点的位置,例如根节点的下标为0,左子节点的下标为2 * i + 1,右子节点的下标为2 * i + 2。
  • 在插入元素时,将新元素插入到数组末尾,然后通过上浮操作将其移动到正确的位置。
  • 在删除元素时,将最后一个元素替换到堆顶,然后通过下沉操作将其移动到正确的位置。
  • 堆排序时,将堆顶元素与最后一个元素交换,然后将堆的大小减一,再通过下沉操作将新的堆顶元素移动到正确的位置。

 小根堆代码实现:

public class MinHeap {private int[] data; // 存储堆元素的数组private int size; // 堆的大小public MinHeap(int capacity) {data = new int[capacity];size = 0;}// 返回堆的大小public int getSize() {return size;}// 返回堆是否为空public boolean isEmpty() {return size == 0;}// 返回父节点的索引private int parent(int index) {return (index - 1) / 2;}// 返回左子节点的索引private int leftChild(int index) {return 2 * index + 1;}// 返回右子节点的索引private int rightChild(int index) {return 2 * index + 2;}// 上浮操作private void siftUp(int index) {while (index > 0 && data[parent(index)] > data[index]) {swap(parent(index), index);index = parent(index);}}// 下沉操作private void siftDown(int index) {while (leftChild(index) < size) {int minIndex = leftChild(index);if (rightChild(index) < size && data[rightChild(index)] < data[minIndex]) {minIndex = rightChild(index);}if (data[index] <= data[minIndex]) {break;}swap(index, minIndex);index = minIndex;}}// 交换两个元素的位置private void swap(int i, int j) {int temp = data[i];data[i] = data[j];data[j] = temp;}// 向堆中插入元素public void insert(int value) {if (size == data.length) {throw new IllegalStateException("Heap is full");}data[size] = value;siftUp(size);size++;}// 从堆中删除最小元素(即堆顶元素)public int extractMin() {if (isEmpty()) {throw new IllegalStateException("Heap is empty");}int minValue = data[0];data[0] = data[size - 1];size--;siftDown(0);return minValue;}
}

也有一个偷懒的办法,我们可以通过 Java 内置的 PriorityQueue 类来实现最小堆。通过调用add() 方法可以向堆中插入元素,而通过调用 poll() 方法可以从堆中删除最小元素(即堆顶元素)。

需要注意的是,PriorityQueue  默认实现的是最小堆,如果需要实现最大堆,可以通过传递自定义比较器来实现。例如,使用 PriorityQueue<Integer>(Conleections.reverseOrder()) 来创建一个最大堆。

public class HeapTest {public static void main(String[] args) {// 创建一个最小堆PriorityQueue<Integer> minHeap = new PriorityQueue<>();// 向堆中插入元素minHeap.add(5);minHeap.add(2);minHeap.add(8);minHeap.add(1);minHeap.add(3);System.out.println("最小堆的元素: " + minHeap); // 输出: [1, 2, 8, 5, 3]// 从堆中删除最小元素(堆顶元素)int minElement = minHeap.poll();System.out.println("被删除的最小元素: " + minElement); // 输出: 1System.out.println("删除最小元素后的最小堆: " + minHeap); // 输出: [2, 3, 8, 5]}
}

7. 应用场景

  • 堆排序:利用最大堆或最小堆的性质,可以进行高效的排序操作。堆排序是一种时间复杂度为O(n log n)的排序算法,它通过建堆和反复删除堆顶元素进行排序。
  • 中位数查询:使用最大堆和最小堆可以在O(log n)的时间内查询一组数据的中位数,这对于实时数据分析等领域非常重要。
  • Top K问题:对于一个数据流,需要在其中找到前K大或前K小的元素,可以使用堆来实现。维护一个大小为K的堆,遍历数组,从数组中取出数据与堆顶元素比较,如果比堆顶元素大,则将堆顶元素删除,并将这个元素插入到堆中;如果比堆顶元素小,则不做处理,继续遍历数组。这样等数组中的数据都遍历完之后,堆中的数据就是前K大数据了。

6. 总结

        综上所述,堆是Java中一种非常重要的基础数据结构,它提供了高效的数据插入和删除操作,广泛应用于堆排序、top k问题等场景。理解堆的基本操作和应用,对于开发者来说非常有益,有助于更好地利用这一数据结构来解决实际问题。

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

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

相关文章

Node安装配置

一、下载 Node官网下载地址&#xff1a;https://nodejs.org/en/ 二、安装 双击上面的msi扩展安装包开始安装&#xff0c;基本一路Next就行了 推荐安装目录自定义&#xff0c;最好不要放在C盘 检查安装是否成功 Win R 快捷键&#xff0c;输入 cmd 打开命令窗口输…

基于Java的超市进销存管理系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; Java JSP Servlet JavaBean 工具&#xff1a; IDEA/Eclipse、…

Elasticsearch 管道查询语言 ES|QL 现已正式发布

作者&#xff1a;Costin Leau, George Kobar 今天&#xff0c;我们很高兴地宣布 ES|QL&#xff08;Elasticsearch 查询语言&#xff09;全面上市&#xff0c;这是一种从头开始设计的动态语言&#xff0c;用于转换、丰富和简化数据调查。在新的查询引擎的支持下&#xff0c;ES|Q…

大模型训练的艺术:从预训练到增强学习的四阶段之旅

文章目录 大模型训练的艺术&#xff1a;从预训练到增强学习的四阶段之旅1. 预训练阶段&#xff08;Pretraining&#xff09;2. 监督微调阶段&#xff08;Supervised Finetuning, SFT&#xff09;3. 奖励模型训练阶段&#xff08;Reward Modeling&#xff09;4. 增强学习微调阶段…

2- 简易版-日记写作软件(java)-涉及的技术点简述

环境&#xff1a; Ubuntu LinuxJDK1.8Eclipse 项目文件结构&#xff1a; 0. 涉及的技术点 1)view 包&#xff08;GUI&#xff09;&#xff1a; Eclipse SwingEclipse WindowBuilderJFileChooser(用于弹出文件选择对话框&#xff0c;进行文件或目录的选择)FileNameExtension…

【SQLAlChemy】filter过滤条件如何使用?

filter 过滤条件 生成 mock 数据 # 创建 session 对象 session sessionmaker(bindengine)()# 本地生成mock数据 for i in range(6):# 生成随机名字, 长度为4到7个字符name .join(random.choice(string.ascii_letters) for _ in range(random.randint(4, 7)))# 生成随机年龄…

矩阵杯2024 Re wp 前两题

1. packpy UPX壳&#xff0c;但不能直接脱&#xff0c;应该是修改了头文件&#xff08;l_info) 改一下就能脱了 脱完是个elf文件 进IDA看一眼 明显的Py打包标志&#xff0c;用pyinstxtractor解包出来&#xff08;最好用对应的python3.8&#xff09; 可以得到packpy.pyc文件&a…

Prov-GigaPath:新型数字病理基础模型|顶刊精析·2024-06-10

小罗碎碎念 顶刊精析&#xff5c;2024-06-10 首先祝各位老师、师兄师姐、师弟师妹们端午节快乐&#xff01;&#xff01;小罗是社恐&#xff0c;所以就不一一发消息问候了&#xff0c;哈哈。 今天这篇推文是昨天下午写完的&#xff0c;想着时间有点晚了&#xff0c;所以就放到…

作业07 递推算法2

作业&#xff1a; #include <iostream> using namespace std; int main(){int a[110][110]{0},b[110][110]{0},n;cin>>n;for(int i1;i<n;i){for(int j1;j<i;j){cin>>a[i][j];}}for(int in-1;i>1;i--){for(int j1;j<i;j){a[i][j]a[i][j]max(a[i1]…

SpringBoot中实现一个通用Excel导出功能

SpringBoot中实现一个通用Excel导出功能 文章目录 SpringBoot中实现一个通用Excel导出功能这个导出功能的特色看效果代码解析1、依赖2、Excel 入参(ExcelExportRequest)3、Excel 出参(ExcelExportResponse)4、ExcelExportField5、ExcelExportUtils 工具类6、ExcelHead 头部…

0元白嫖阿里云4G内存云服务器——感谢伟大的CSDN和阿里云

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对博主首页也很感兴趣o (ˉ▽ˉ&#xff1b;) 学生邮箱白嫖/免费安装JetBrains全家桶(IDEA/pycharm等) —— 保姆级教程-CSDN博客 目录 1、学生认证领取300元优惠券 ​2、购买云服务器 1、学生认证领取…

深度学习500问——Chapter10:迁移学习(1)

文章目录 11.1 迁移学习基础知识 11.1.1 什么是迁移学习 11.1.2 为什么需要迁移学习 11.1.3 迁移学习的基本问题有哪些 11.1.4 迁移学习有哪些常用概念 11.1.5 迁移学习与传统机器学习有什么区别 11.1.6 迁移学习的核心及度量准则 11.1.7 迁移学习与其他概念的区别 11.1.8 什么…

tcp协议中机制的总结

目录 总结 分析 三次握手 总结 分析 其中,序列号不止用来排序,还可以用在重传时去重 确认应答是机制中的核心 因为都需要依靠应答来拿到协议字段,从而判断是否触发机制 保证可靠性的策略也可以提高效率,比如: 流量控制,可以根据多个因素来动态调整数据发送量拥塞控制也是,让…

揭开FFT时域加窗的奥秘

FFT – Spectral Leakage 假设用于ADC输出数据分析的采样点数为N&#xff0c;而采样率为Fs&#xff0c;那我们就知道&#xff0c;这种情况下的FFT频谱分辨率为δf&#xff0c;那么δfFs/N。如果此时我们给ADC输入一个待测量的单频Fin&#xff0c;如果此时Fin除以δf不是整数&a…

翻译《The Old New Thing》- Why do messages posted by PostThreadMessage disappear?

Why do messages posted by PostThreadMessage disappear? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20090930-00/?p16553 Raymond Chen 2008年09月30日 为什么 PostThreadMessage 发布的信息会消失&#xff1f; 在显示用户界面的线…

【Java】网制焦,实也难,0基础,学反射

【Java】网制焦&#xff0c;实也难&#xff0c;0基础&#xff0c;学反射 文章目录 【Java】网制焦&#xff0c;实也难&#xff0c;0基础&#xff0c;学反射反射的概述 获取Class对象的三种方式通过对象的getClass()方法通过类的静态属性class通过Class.forName()方法 通过反射获…

新技术前沿-2023-大模型学习根据个人数据集微调一个Transformer模型

参考如何根据自己的数据集微调一个 Transformer 模型 我们将通过NLP中最常见的文本分类任务来学习如何在自己的数据集上利用迁移学习(transfer learning)微调一个预训练的Transformer模型——DistilBERT。DistilBERT是BERT的一个衍生版本&#xff0c;它的优点在它的性能与BERT相…

Vue14-监视属性

一、天气案例 1-1、方式一&#xff1a;{{三目运算符}} 1-2、方式二&#xff1a;计算属性 1-3、方式三&#xff1a;click中写简单逻辑 click里面可以写简单的逻辑语句。不用this 解决方式&#xff1a; 小结&#xff1a; 绑定事件的时候&#xff0c;xxx"yyy" xxx&…

C语言学习系列:GCC编译器Windows版本MinGW-w64的安装教程

本文图文分享如何安装C语言编译器——MinGW-w64。 只要看到这篇文章&#xff0c;就可以按照文中步骤正确安装MinGW-w64并使用。 一、什么是 MinGW-w64 &#xff1f; 我们知道C语言是高级语言&#xff0c;必须编译为二进制文件&#xff0c;才能为计算机运行&#xff0c;MinGW…

理解我的积木编程思想

1 学习教程&#xff0c;至少7139手册2 编程实践&#xff0c;遇到实际问题后&#xff0c;在技术资料中查找关键词3 选择适合的条目找到代 码。修正&#xff0c;组合。