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

详细介绍数据结构-堆

计算机中的堆数据结构

什么是堆

在计算机科学中,堆(Heap)是一种重要的数据结构,它用于在动态分配时存储和组织数据。堆是一块连续的内存区域,其中每个存储单元(通常是字节)都与另一个存储单元紧密相邻。

堆和栈是计算机内存的两种主要部分。其中,栈用于存储局部变量和函数调用的信息,而堆则用于存储动态分配的变量和数据结构。

堆的特点是可以动态地增加和减少内存,而且可以任意分配内存的大小。这意味着你可以在运行时分配内存,以存储例如动态数组,图形数据结构,优先级队列等数据。

堆的好处及适用场景

堆数据结构有许多优点,这使得它在许多计算场景中都非常有用。

  1. 动态内存分配:堆允许我们在运行时动态地分配和释放内存。这意味着我们可以在程序执行的过程中,根据需要创建或删除数据。
  2. 大小不定:与栈不同,堆的大小不是预先确定的。这意味着我们可以用它来存储大量的数据,只要可用的系统内存允许。
  3. 支持自定义数据类型:由于堆是通用的内存分配机制,因此可以用它来存储任何类型的数据,不仅仅是基本类型。

下面是一些适用的场景:

  • 动态数组:堆是创建动态数组(例如动态调整大小的数组)的理想场所。你可以在运行时根据需要增加或减少数组的大小。
  • 优先级队列:优先级队列经常使用堆来实现。在这种情况下,堆的特性允许我们有效地插入和删除元素,以及在O(1)时间内查找最大(或最小)元素。
  • 动态链接列表:在动态链接列表中,我们需要在运行时创建和删除节点。这也需要使用堆内存。
  • 图形和树结构:图形和树结构通常使用堆来实现,因为这些数据结构需要在运行时动态地添加和删除节点。

C++代码实现一个堆并测试

以下是一个简单的最小堆的C++实现。注意这个例子只是为了教育目的,并没有包含一些关键的功能,比如防止溢出或检查是否溢出。

然后,我们可以继续实现其他堆操作,例如删除元素,查找最小元素等。以下是一个更完整的堆实现,包括上述缺失的操作:

#include <iostream>  
#include <vector>  
#include <stdexcept>  // for std::out_of_range  class MinHeap {  
private:  std::vector<int> data;  // underlying data structure  int parent(int i) { return (i - 1) / 2; }  // parent index  int leftChild(int i) { return 2 * i + 1; }  // left child index  int rightChild(int i) { return 2 * i + 2; }  // right child index  void siftUp(int i) {  // sift element i up to its proper place  while (i > 0 && data[parent(i)] > data[i]) {  std::swap(data[parent(i)], data[i]);  i = parent(i);  }  }  void siftDown(int i) {  // sift element i down to its proper place  int minIndex = i;  // index of current minimum element  int l = leftChild(i);  // left child index  if (l < data.size() && data[l] < data[minIndex]) {  minIndex = l;  }  int r = rightChild(i);  // right child index  if (r < data.size() && data[r] < data[minIndex]) {  minIndex = r;  }  if (i != minIndex) {  // swap i and minIndex if necessary and repeat siftDown on affected subtree  std::swap(data[i], data[minIndex]);  siftDown(minIndex);  }  }  void siftUpForInsert(int i) {  // sift element i up to its proper place after insert for heap property to be maintained  while (i > 0 && data[parent(i)] > data[i]) {  std::swap(data[parent(i)], data[i]);  i = parent(i);  }  }  public:  void insert(int value) {  // insert value into heap and maintain heap order property  data.push_back(value);  // append value to the end of the vector and remember its index (size - 1)  siftUpForInsert(data.size() - 1);  // sift up to maintain heap order property (parent is larger than its children) after insert  }  int extractMin() {  // extract the current minimum element from heap and maintain heap order property  if (data.empty()) { throw std::out_of_range("Heap is empty"); }  // heap is empty, so there is no min element throw an exception here to indicate that the situation cannot be handled and the program should stop execution with an error message to user indicating the error situation that occurred here.  int minElement = data[0];  // store the minimum element in a temporary variable minElement before swapping it with the last element in the vector and deleting it from the vector in the next step (data.pop_back()) as this will change the size of the vector and all further indices will shift downwards by one position in memory.  std::swap(data[0], data[data.size() - 1]);  // swap the first element with the last element in the vector as they will have swapped roles after this step (the last element will become the new first element/minimum element in its new position in memory while the first element will become the last element in its new position in memory after this swap operation) for maintaining the heap property after extract operation.  data.pop_back();  // remove the last element from the vector as it has just become unnecessary/redundant/no longer required in memory after the previous swapping step to maintain heap order property as required. As it is removed, all further indices will shift downwards by one position in memory for maintaining the heap property after extract operation.  siftDown(0);  // sift down the new first element/minimum element to maintain heap order property after extract operation as required. The root/first element is always at index 0 in a heap as shown in all figures above for heap data structure shown above in this code segment also. Heap is a complete binary tree (each node has either two children or no children). Binary tree is a type of tree where each node has}

相关文章:

详细介绍数据结构-堆

计算机中的堆数据结构 什么是堆 在计算机科学中&#xff0c;堆&#xff08;Heap&#xff09;是一种重要的数据结构&#xff0c;它用于在动态分配时存储和组织数据。堆是一块连续的内存区域&#xff0c;其中每个存储单元&#xff08;通常是字节&#xff09;都与另一个存储单元…...

001flutter基础学习

flutter基础学习 参考:https://book.flutterchina.club/chapter1/flutter_intro.html Flutter是谷歌的移动UI框架跨平台: Linux,Android, IOS,Fuchsia原生用户界面:它是原生的,让我们体验更好,性能更好开源免费&#xff1a;完全开源,可以进行商用Flutter与主流框架的对比 Cor…...

leetCode 1143.最长公共子序列 动态规划 + 图解

此题我的往期文章推荐&#xff1a; leetCode 1143.最长公共子序列 动态规划 滚动数组-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/133689692?spm1001.2014.3001.5501leetCode 1143.最长公共子序列 一步步思考动态规划 优化空间复杂度_呵呵哒(&#xf…...

解密人工智能:KNN | K-均值 | 降维算法 | 梯度Boosting算法 | AdaBoosting算法

文章目录 一、机器学习算法简介1.1 机器学习算法包含的两个步骤1.2 机器学习算法的分类 二、KNN三、K-均值四、降维算法五、梯度Boosting算法和AdaBoosting算法六、结语 一、机器学习算法简介 机器学习算法是一种基于数据和经验的算法&#xff0c;通过对大量数据的学习和分析&…...

Python深度学习实践

线性模型 课程 import numpy as np import matplotlib.pyplot as plt x_data[1.0,2.0,3.0] y_data[2.0,4.0,6.0] #前馈函数 def forward(x):return x*w #损失函数 def loss(x,y):y_predforward(x)return (y_pred-y)*(y_pred-y) w_list[] mse_list[] for w in np.arange(0.0,4…...

VS2017+QT+PCL环境配置

前言: 最近自己再弄一下小项目中需要用到pcl来开发点云的显示,但是却遇到很多坑,所以记录下来分析给知音人。 避雷:由于vtk和pcl之间有版本以来关系,但是安装过程是不变的。 选择对应的版本参考如下安装: pcl1.8.1依赖vtk版本7.1.1;pcl1.9.1至pcl1.12.0依赖vtk最低版本为…...

207、SpringBoot 整合 RabbitMQ 实现消息的发送 与 接收(监听器)

目录 ★ 发送消息★ 创建队列的两种方式代码演示需求1&#xff1a;发送消息1、ContentUtil 先定义常量2、RabbitMQConfig 创建队列的两种方式之一&#xff1a;配置式&#xff1a;问题&#xff1a; 3、MessageService 编写逻辑PublishController 控制器application.properties 配…...

想要精通算法和SQL的成长之路 - 滑动窗口和大小根堆

想要精通算法和SQL的成长之路 - 滑动窗口和大小根堆 前言一. 大小根堆二. 数据流的中位数1.1 初始化1.2 插入操作1.3 完整代码 三. 滑动窗口中位数3.1 在第一题的基础上改造3.2 栈的remove操作 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 大小根堆 先来说下大小根堆是什…...

Python算法练习 10.15

leetcode 2130 链表的最大孪生和 在一个大小为 n 且 n 为 偶数 的链表中&#xff0c;对于 0 < i < (n / 2) - 1 的 i &#xff0c;第 i 个节点&#xff08;下标从 0 开始&#xff09;的孪生节点为第 (n-1-i) 个节点 。 比方说&#xff0c;n 4 那么节点 0 是节点 3 的孪…...

智能防眩目前照灯系统控制器ADB

经纬恒润的自适应远光系统—— ADB&#xff08;Adaptive Driving Beam&#xff09; 是一种能够根据路况自适应变换远光光型的智能远光控制系统。根据本车行驶状态、环境状态以及道路车辆状态&#xff0c;ADB 系统自动为驾驶员开启或退出远光。同时&#xff0c;根据车辆前方视野…...

若依 ruoyi 路径 地址 # 井号去除

export default new Router({mode: history, // history 去掉url中的# 、hash 包含#号scrollBehavior: () > ({ y: 0 }),routes: constantRoutes })...

Elasticsearch 和 Arduino:一起变得更好!

作者&#xff1a;Enrico Zimuel 使用 Arduino IoT 设备与 Elasticsearch 和 Elastic Cloud 进行通信的简单方法 在 Elastic&#xff0c;我们不断寻找简化搜索体验的新方法&#xff0c;并开始关注物联网世界。 来自物联网的数据收集可能非常具有挑战性&#xff0c;尤其是当我们…...

基于Ubuntu环境Git 服务器搭建及使用

多人合作开发的时候 常常会需要使用代码管理平台&#xff0c;保持代码一致和解决冲突。在工作中我使用过SVN和TFS&#xff0c;本文说明另外一种平台&#xff0c;Git&#xff0c;下面是基于Ubuntu环境安装并简单使用Git服务器。 确认安装git apt install git levilevi-ThinkPa…...

【quartus13.1/Verilog】swjtu西南交大:计组课程设计

实验目的&#xff1a; 通过学习简单的指令系统及其各指令的操作流程&#xff0c;用 Verilog HDL 语言实 现简单的处理器模块&#xff0c;并通过调用存储器模块&#xff0c;将处理器模块和存储器模块连接形成简 化的计算机核心部件组成的系统。 二. 实验内容 1. 底层用 Verilog…...

基于springboot的网上点餐系统论文开题报告

一、选题背景 随着互联网和移动互联网技术的快速发展&#xff0c;网上点餐成为了人们越来越喜欢的一种点餐方式。一些具有创新意识的餐厅也开始逐渐尝试利用互联网技术来提升用户的点餐体验。因此&#xff0c;开发一个基于Spring Boot的网上点餐系统就显得非常必要和重要。 二…...

Hadoop3教程(九):MapReduce框架原理概述

文章目录 简介参考文献 简介 这属于整个MR中最核心的一块&#xff0c;后续小节会展开描述。 整个MR处理流程&#xff0c;是分为Map阶段和Reduce阶段。 一般&#xff0c;我们称Map阶段的进程是MapTask&#xff0c;称Reduce阶段是ReduceTask。 其完整的工作流程如图&#xff…...

使用PyTorch加载数据集:简单指南

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…...

【考研数学】线性代数第六章 —— 二次型(2,基本定理及二次型标准化方法)

文章目录 引言一、二次型的基本概念及其标准型1.2 基本定理1.3 二次型标准化方法1. 配方法2. 正交变换法 写在最后 引言 了解了关于二次型的基本概念以及梳理了矩阵三大关系后&#xff0c;我们继续往后学习二次型的内容。 一、二次型的基本概念及其标准型 1.2 基本定理 定理…...

Raven2靶机渗透

1. 信息收集 1.1 主机探测 sudo arp-scan -l1.2 端口扫描 nmap -p- -A 192.168.16.185开放了80端口&#xff0c;尝试登录网址查看信息&#xff0c;通过浏览器插件找出指纹 1.3 目录扫描 访问登录界面&#xff0c;发现remember Me怀疑是shiro界面 登录/vendor/界面&#xff0…...

UE5中双pass解决半透明材质乱序问题

透明度材质乱序问题一直是半透明效果时遇到的比较多的问题&#xff0c;用多pass方案只能说一定程度上解决&#xff0c;当遇到多半透明物体穿插等情况时&#xff0c;仍然不能完美解决。 双pass方案Unity用的比较多&#xff0c;因为Unity支持多个pass绘制。在UE中我们可以以复制多…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

Docker 运行 Kafka 带 SASL 认证教程

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

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...