【手写大跟堆详解】

文章目录

  • 大跟堆介绍
  • 大跟堆的结构
  • 大跟堆的应用场景
  • 大跟堆的代码实现

大跟堆介绍

大根堆(Max Heap)是一种特殊的二叉树结构,它满足以下两个条件:
1.完全二叉树:大根堆是一棵完全二叉树,即除了最后一层外,其余每一层的节点都是满的,最后一层的节点都集中在最左边。
2.堆性质:每个节点的值都大于或等于其子节点的值。
大根堆的典型操作包括插入,获取root节点的最大值。
在这里插入图片描述

大跟堆的结构

大根堆的结构
大根堆可以用数组来表示,因为它是一棵完全二叉树。对于一个存储在数组中的大根堆:
根节点的索引为 0。
给定一个节点的索引位置i:
父节点的索引为 (i - 1) / 2。
左子节点的索引为 2 * i + 1。
右子节点的索引为 2 * i + 2。

大跟堆的应用场景

大根堆(Max Heap)在许多算法和应用中都有重要的作用,特别是在需要频繁访问最大元素的场景中。以下是一些常见的应用场景:

  1. 优先队列
    优先队列是一种特殊的队列,每次出队的元素都是队列中优先级最高的元素。大根堆可以用来实现优先队列,其中堆顶元素始终是优先级最高的元素。
    应用举例:
    操作系统的任务调度:调度器选择优先级最高的任务进行执行。
    网络数据包处理:路由器处理优先级最高的数据包。
  2. 堆排序
    堆排序是一种利用堆数据结构设计的排序算法。其基本思想是将待排序序列构建成一个大根堆,此时整个序列的最大值即为堆顶元素。将堆顶元素移出堆(与堆的最后一个元素交换),然后对剩余元素重新构建堆,反复执行上述操作,直到所有元素有序。
    应用举例:
    大数据集的排序:在需要对大量数据进行排序时,堆排序的空间效率较高。
  3. 动态数据流中的最大值
    在处理动态数据流时,使用大根堆可以实时维护当前数据流中的最大值。
    应用举例:
    股票交易系统:实时维护当前交易中的最大交易量。
    传感器数据监控:实时监控传感器数据流中的最大值。
  4. 找到第 K 大的元素
    在一个无序数组中查找第 K 大的元素,可以使用大根堆来实现。首先构建一个包含数组中前 K 个元素的大根堆,然后遍历数组剩余元素,如果当前元素小于堆顶元素,则替换堆顶元素并调整堆,最终堆顶元素即为第 K 大的元素。
    应用举例:
    排名系统:在一组分数中找到第 K 高的分数。
    数据分析:在一组数据中找到第 K 大的数据点。
  5. 合并多个有序序列
    在合并多个有序序列时,可以使用大根堆来保持当前最小元素的顺序。将每个序列的首元素插入大根堆,然后每次取出堆顶元素并插入其所在序列的下一个元素,直到所有元素都被处理完毕。
    应用举例:
    外部排序:当数据量大到无法全部放入内存时,可以先将数据分块排序,然后合并多个有序块。
    多路归并排序:将多个有序的输入流合并为一个有序的输出流。
  6. 图的最短路径算法(如 Dijkstra 算法)
    在 Dijkstra 算法中,需要使用优先队列来选择当前未访问节点中距离起点最近的节点。大根堆可以用来实现这个优先队列,以保证每次都能高效地选择最短路径的下一步节点。
    应用举例:
    地图导航系统:计算从一个地点到另一个地点的最短路径。
    网络路由优化:寻找数据包在网络中传输的最优路径。
  7. 事件驱动模拟
    在事件驱动的模拟系统中,需要按照事件的发生时间顺序来处理事件。使用大根堆可以有效地管理和调度这些事件。
    应用举例:
    离散事件模拟:如模拟交通流、制造过程等。
    计算机图形学:处理动画中事件的时间调度。

大跟堆的代码实现

插入操作:
插入新元素时,将元素添加到数组的末尾(完全二叉树的最后一个位置),然后进行“上浮”操作(也称为堆化)以恢复堆的性质。
上浮操作:
将新元素与其父节点比较,如果大于父节点,则交换位置,继续向上比较,直到元素小于或等于父节点,或者到达根节点。

public void insert(int key) {if (size == capacity) {throw new RuntimeException("Heap is full");}heap[size] = key; // 将新元素放在堆尾int current = size;size++;// 上浮操作while (current != 0 && heap[parent(current)] < heap[current]) {swap(parent(current), current);current = parent(current);}
}

2.删除最大值操作:
删除最大值(根节点)时,将数组的最后一个元素移动到根节点位置,然后进行“下沉”操作(也称为堆化)以恢复堆的性质。
下沉操作:
将根节点与其左右子节点比较,如果小于其中一个子节点,则与较大的子节点交换位置,继续向下比较,直到元素大于或等于子节点,或者到达叶节点。

public int extractMax() {if (size <= 0) {throw new RuntimeException("Heap is empty");}int root = heap[0]; // 保存根节点heap[0] = heap[size - 1]; // 将最后一个元素移到根节点位置size--;// 下沉操作maxHeapify(0);return root;
}private void maxHeapify(int i) {int largest = i;int left = leftChild(i);int right = rightChild(i);if (left < size && heap[left] > heap[largest]) {largest = left;}if (right < size && heap[right] > heap[largest]) {largest = right;}if (largest != i) {swap(i, largest);maxHeapify(largest);}
}

3.交换元素:
在堆的操作过程中,经常需要交换两个节点的位置。

private void swap(int i, int j) {int temp = heap[i];heap[i] = heap[j];heap[j] = temp;
}

4.完整的大根堆实现
以下是大根堆的完整实现,包括构造函数、插入操作、删除最大值操作和辅助方法。

public class MaxHeap {private int[] heap;private int size;private int capacity;// 构造函数public MaxHeap(int capacity) {this.capacity = capacity;this.heap = new int[capacity];this.size = 0;}// 获取父节点索引private int parent(int i) { return (i - 1) / 2; }// 获取左子节点索引private int leftChild(int i) { return 2 * i + 1; }// 获取右子节点索引private int rightChild(int i) { return 2 * i + 2; }// 插入新元素public void insert(int key) {if (size == capacity) {throw new RuntimeException("Heap is full");}heap[size] = key; // 将新元素放在堆尾int current = size;size++;// 上浮操作while (current != 0 && heap[parent(current)] < heap[current]) {swap(parent(current), current);current = parent(current);}}// 提取最大元素(根节点)public int extractMax() {if (size <= 0) {throw new RuntimeException("Heap is empty");}int root = heap[0]; // 保存根节点heap[0] = heap[size - 1]; // 将最后一个元素移到根节点位置size--;// 下沉操作maxHeapify(0);return root;}// 下沉操作private void maxHeapify(int i) {int largest = i;int left = leftChild(i);int right = rightChild(i);if (left < size && heap[left] > heap[largest]) {largest = left;}if (right < size && heap[right] > heap[largest]) {largest = right;}if (largest != i) {swap(i, largest);maxHeapify(largest);}}// 交换元素private void swap(int i, int j) {int temp = heap[i];heap[i] = heap[j];heap[j] = temp;}// 主函数示例public static void main(String[] args) {MaxHeap maxHeap = new MaxHeap(10);maxHeap.insert(3);maxHeap.insert(1);maxHeap.insert(4);maxHeap.insert(1);maxHeap.insert(5);maxHeap.insert(9);maxHeap.insert(2);maxHeap.insert(6);maxHeap.insert(5);System.out.println("Extracted max: " + maxHeap.extractMax());System.out.println("Extracted max: " + maxHeap.extractMax());System.out.println("Extracted max: " + maxHeap.extractMax());}
}

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

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

相关文章

一分钟快速排序

这个 quick_sort 函数是一个实现快速排序&#xff08;Quicksort&#xff09;算法的递归函数。快速排序是一种高效的排序算法&#xff0c;通常用于对大规模数据集进行排序。以下是对该函数的详细解释&#xff1a; 函数签名 void quick_sort(int q[], int l, int r)q[]&#xf…

Qt_电脑wifi相关操作

项目描述: 在做项目时用到了获取wifi的操作。在网上查找了好久资料,这里做一些总结。 这里有显示当前电脑wifi连接状态,列出wifi列表,连接断开wifi等函数。欢迎大家留言添加文章内容。 使用范围: windows电脑(中文的环境) 使用技术:windows的cmd命令。和对字符串的解析…

C语言学习笔记--运算符与表达式(7521字爆肝)

上午好&#xff0c;本来想上午改简历下午学习c语言的&#xff0c;但想了一下上午精力充沛还是用来学习比较好&#xff0c;虽然现在失业了&#xff0c;但住在我姨家有吃有住的&#xff0c;再次感谢我姨&#xff0c;我要抓紧时间修改简历&#xff0c;然后找个工作搬出去&#xff…

【回忆版】数据科学思维与大数据智能分析 2024考试

填空&#xff08;18分&#xff09;18个 1.对数变换对大数值的范围进行压缩&#xff0c;对小数值的范围进行扩展 2.提取出大量高频率项与低频率项相关联的虚假模式&#xff0c;即交叉支持&#xff08;cross-support&#xff09;模式 3.信息论中&#xff08;&#xff09; 4.几种…

[数据集][目标检测]弹簧上料检测数据集VOC+YOLO格式142张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;142 标注数量(xml文件个数)&#xff1a;142 标注数量(txt文件个数)&#xff1a;142 标注类别…

yolov8训练自己数据集时出现loss值为nan。

具体原因目前暂未寻找到。 解决办法 将参数amp改成False即可。 相关资料&#xff1a; https://zhuanlan.zhihu.com/p/165152789 https://github.com/ultralytics/ultralytics/issues/1148

【BUG】Edge|联想电脑 Bing 搜索报错“Ref A: 乱码、 Ref B:乱码、Ref C: 日期” 的解决办法

文章目录 省流版前言解决办法 详细解释版前言问题描述与排查过程解决办法与总结 省流版 前言 我也不清楚咋滴了&#xff0c;Bing 搜索突然偶尔报错&#xff1a; 换了代理关了插件都报错。 参考&#xff1a; 我在用bing搜索时出现了如下代码&#xff0c;导致bing无法使用&am…

nginx proxy_set_header详解

proxy_set_header 是 Nginx 配置中的一个重要指令&#xff0c;特别是在使用 Nginx 作为反向代理时。该指令允许你修改由 Nginx 传递给代理后端的请求头。这对于确保后端应用程序能够接收到正确的客户端信息&#xff08;如 IP 地址、主机名等&#xff09;以及控制缓存行为等场景…

1 计算机硬件-CPU-校验码-存储系统-输入输出设备-总线结构

计算机硬件 考情分析&#xff1a;趋势很小&#xff0c;22年考过&#xff0c;根据趋势以后考的可能较小 基本组成&#xff1a;运算器&#xff0c;控制器&#xff0c;储存器&#xff0c;输入设备&#xff0c;输出设备运算器和控制器也统称为中央处理单元&#xff08;CPU&#xf…

【算法训练 day37 柠檬水找零、长度最小的子数组、用最少数量的箭引爆气球】

目录 一、柠檬水找零-LeetCode 860思路实现代码个人问题总结 二、根据身高重建队列-LeetCode 406思路实现代码个人问题总结 三.用最少数量的箭引爆气球-LeeCode 406思路实现代码个人问题总结 一、柠檬水找零-LeetCode 860 Leecode链接: leetcode 860 文章链接: 代码随想录 视频…

解锁Nginx跨域谜题:3步打造安全高效的CORS策略

Nginx作为一款强大的Web服务器和反向代理服务器&#xff0c;经常被用于处理跨域资源共享&#xff08;CORS&#xff0c;Cross-Origin Resource Sharing&#xff09;策略&#xff0c;以允许或限制不同源之间的资源请求。CORS是一种安全策略&#xff0c;用于决定Web浏览器是否应允…

深度学习——图像分类(CNN)—测试模型

测试模型 1.导入必要的库2.加载测试数据集3.假设CSV文件中的图像文件名是完整的路径4.随机选择一张图片进行展示5.加载图像6.使用模型进行预测7.设置模型的预测结果8.计算准确率9.指定test文件夹路径10.读取名为image_path的图片11.加载图像12.检查图像是否为空 训练的模型是上…

eNSP学习——OSPF单区域配置

目录 相关命令 实验背景 实验目的 实验步骤 实验拓扑 实验编址 实验步骤 1、基础配置 2、部署单区域OSPF网络 3、检查OSPF单区域的配置结果 OSPF——开放式最短路径优先 基于链路状态的协议&#xff0c;具有收敛快、路由无环、扩展性好等优点&#xff1b; 相关命令 […

【JAVA基础之内部类】匿名内部类

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;小林同学的专栏&#xff1a;JAVA之基础专栏 目录 1.内部类 1.1 概述 1.1.1 什么是内部类 1.1.2 什么时候使用内部类 1.2 内部类的分类 1.3 成员内部类 1.3.1 获取成员内部类对象的两种方式 1.3.2 经典面试…

用C语言把一棵普通二叉树安排得明明白白

1. 树的相关术语 结点的度&#xff1a;一个结点含有的子树的个数称为该结点的度&#xff1b; 如上图&#xff1a;A的为6 叶结点或终端结点&#xff1a;度为0的结点称为叶结点&#xff1b; 如上图&#xff1a;B、C、H、I...等结点为叶结点 非终端结点或分支结点&#xff1a;度不…

【Linux】-Tomcat安装部署[12]

目录 简介 安装 安装部署JDK环境 解压并安装Tomcat 简介 Tomcat是由Apache开发的一个Servlet容器&#xff0c;实现了对Servlet和JSP的支持&#xff0c;并提供了作为Web服务器的一些特有功能&#xff0c;如Tomcat管理和控制平台、安全域管理和Tomcat阀等。 简单来说&#…

使用 mysql-binlog-connector 监听处理 MySQLBinlog 文件

1. 需求概述 业务开发中经常需要根据一些数据变更实现相对应的操作。例如&#xff0c;一些用户注销自己的账户&#xff0c;系统可以给用户自动发短信确认&#xff0c;这时有两种解决方案&#xff0c;一种是耦合到业务系统中&#xff0c;当用户执行注销操作的时候&#xff0c;执…

【软件工程】【23.10】p2

关键字&#xff1a; 软件复用技术、过程途径、特定需求是文档核心、数据字典条目、高内聚低耦合独立性、数据流图映射模块结构图、UML依赖、用例图关系、RUB迭代、程序规格说明等价类划分、有效性测试的目标、喷泉模型面向对象、软件验证过程、CMMI

算法提高之程序自动分析

算法提高之程序自动分析 核心思想&#xff1a;并查集 离散化 因为不是每个数都会用到 所以离散化一下**(不需要保留顺序)**对于每一个值为1的等式 优先处理之后处理值为0的等式时 若ab已经连在一起 即为矛盾 #include <iostream>#include <cstring>#include &l…

【Linux】Centos7安装RabbitMQ

【Linux】Centos7安装RabbitMQ 下载 从 rabbitmq 的 GitHub 仓库下载 https://github.com/rabbitmq/rabbitmq-server/releases rabbitmq 是 erlang 语言编写的&#xff0c;需要先安装 erlang https://github.com/rabbitmq/erlang-rpm/releases 安装 使用rz命令上传 erlang 和 …