数据结构 - 堆

这篇博客将介绍堆的概念以及堆的实现。

1. 堆的定义:
首先堆的元素按照是完全二叉树的顺序存储的。
且堆中的某个节点总是不大于不小于其父节点的值。
根节点最大的堆叫做大堆,根节点最小的堆叫小堆。逻辑结构如下图所示:

大堆和小堆的存储方式是利用一个一维数组进行存储的,其物理存储结构如下:

因此我们可以利用数组的下标,通过子节点找到父节点,或通过父节点找到子节点,其关系如下:
        parent = ( child - 1 ) / 2; child =  parent * 2 + 1;
2. 堆的创建
那么,现在我们有一个数组 a[] = {8, 1, 4, 5, 3, 2};  在逻辑上可以看成一个完全二叉树,但是它还不是一个堆,我们要如何将其构建成一个堆呢?这里我们以构建一个小堆为例,我们从倒数第一个非叶子节点的子树开始调整,一直调整到根节点的树,就可以调整成堆,示意图如下:
3. 堆的插入 
堆的插入一般插入到数组尾部,在进行向上调整算法,直到满足堆的定义 ,示意图如下:

4. 堆的删除
 堆的删除是删除堆顶的数据,将堆顶的根数据与最后一个数据交换,在删除数组的最后一个元素,在进行向下调整堆。示意图如下:

5. 代码实现
typedef int HPDataType;typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;void HeapInit(HP* php);//堆的初始化
void HeapDestroy(HP* php);//内存释放
void HeapPush(HP* php, HPDataType x);//堆的创建
void HeapPop(HP* php);//删除根节点
HPDataType HeapTop(HP* php);//返回根节点
bool HeapEmpty(HP* php);//判空
int HeapSize(HP* php);//堆大小
void HeapInit(HP* php)
{assert(php);php->a = NULL;php->capacity = 0;php->size = 0;
}void HeapDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->size = 0;php->capacity = 0;
}void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}void Adjustup(HPDataType* a, int child)//小堆调整
{int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void HeapPush(HP* php, HPDataType x)
{if (php->size == php->capacity){int newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, newCapacity * sizeof(HPDataType));if (tmp == NULL){perror("realloc fail");return;}php->a = tmp;php->capacity = newCapacity;}php->a[php->size] = x;php->size++;Adjustup(php->a, php->size-1);
}void AdjustDown(int* a, int n, int parent)//前提:左子树和右子树是大/小堆 
{int child = parent * 2 + 1;while (child < n){//选出左右孩子中 小/大 的那个if (child+1 < n && a[child + 1] < a[child])//右孩子可能不存在{child++;}if (a[parent] > a[child]){Swap(&a[parent],&a[child]);parent = child;child = parent * 2 + 1;}else{break;}}
}void HeapPop(HP* php)//删除堆顶的数据
//首尾数据交换,再删除,再调堆
{assert(php);assert(!HeapEmpty(php));Swap(&php->a[0], &php->a[php->size-1]);php->size--;AdjustDown(php->a,php->size,0);
}HPDataType HeapTop(HP* php) 
{assert(php);assert(!HeapEmpty(php));return php->a[0];
}bool HeapEmpty(HP* php)
{assert(php);return php->size == 0;
}int HeapSize(HP* php) 
{assert(php);return php->size;
}
6. 结果
完全二叉树:
int a[] = { 8,1,4,5,3,2 };
建堆:

打印根节点,删除根节点,内存释放: 
while (!HeapEmpty(&hp))
{int top = HeapTop(&hp);printf("%d\n", top);HeapPop(&hp);
}HeapDestroy(&hp);


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

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

相关文章

VBA_NZ系列工具NZ02:VBA读取PDF使用说明

我的教程一共九套及VBA汉英手册一部&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到数据库&#xff0c;到字典&#xff0c;到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑&#xff0c;这么多知识点该如何组织…

使用IDEA远程Debug调试

文章目录 背景配置IDEA设置启动脚本改造 细节细节1&#xff1a;停在本地断点&#xff0c;关闭程序后会继续执行吗?细节2&#xff1a;jar包代码和本地不一致会怎么样&#xff1f;细节3&#xff1a;日志打印在哪里&#xff1f;细节4&#xff1a;调试时其他人会不会卡住&#xff…

【Prometheus】k8s集群部署node-exporter

​ 目录 一、概述 1.1 prometheus简介 1.2 prometheus架构图 1.3 Exporter介绍 1.4 监控指标 1.5 参数定义 1.6 默认启用的参数 1.7 prometheus如何收集k8s/服务的–三种方式收集 二、安装node-exporter组件 【Prometheus】概念和工作原理介绍-CSDN博客 【云原生】ku…

【STM32】HAL库 CubeMX 教程 --- 高级定时器 TIM1 定时

实验目标&#xff1a; 通过CUbeMXHAL&#xff0c;配置TIM1&#xff0c;1s中断一次&#xff0c;闪烁LED。 一、常用型号的TIM时钟频率 1. STM32F103系列&#xff1a; 所有 TIM 的时钟频率都是72MHz&#xff1b;F103C8不带基本定时器&#xff0c;F103RC及以上才带基本定时器。…

C++11——智能指针

本文将解决一下几个问题 1.什么是智能指针 2.为什么需要之智能指针 3.智能指针的使用场景 智能指针 RAII&#xff1a;是一种利用对象声明周期来控制的程序资源&#xff08;如内存、文件句柄、网络连接、互斥量等&#xff09;的技术 在对象构造的时候获取资源&#xff0c;接…

Navicat、phpMyAdmin本地安装

一、Navicat安装 注&#xff1a;本次关于Navicat的安装版本为Navicat160的windows版本 1、从官方下载安装包并安装 官方下载链接为 ​​https://download.navicat.com.cn/download/navicat160_premium_cs_x64.exe​​ 下载完成后&#xff0c;直接进行安装即可&#xff08;…

Unity 整体界面淡入淡出效果

在Unity中&#xff0c;如果我们要实现控制多个组件同时淡出&#xff0c;同时淡入的效果&#xff0c;可以使用DOTween插件实现。 如图&#xff0c;一个页面中带有背景&#xff0c;一张图片&#xff0c;一个文本&#xff0c;一个滑动条。 要实现以上界面的整体淡入淡出&#xff…

C语言连接【MySQL】

稍等更新图片。。。。 文章目录 安装 MySQL 库连接 MySQLMYSQL 类创建 MySQL 对象连接数据库关闭数据库连接示例 发送命令设置编码格式插入、删除或修改记录查询记录示例 参考资料 安装 MySQL 库 在 CentOS7 下&#xff0c;使用命令安装 MySQL&#xff1a; yum install mysq…

R语言:多值提取到点

ArcGIS中有相关工具实现多值提取到点的功能&#xff0c;在这里&#xff0c;我将使用R语言进行操作&#xff1a; library(dplyr) library(readxl) library(sf) library(raster)setwd("D:/Datasets") Bio <- stack(paste0("D:/Datasets/Data/worldclim2_1km/…

【C++】了解一下STL

个人主页 &#xff1a; zxctscl 如有转载请先通知 STL 1. 什么是STL2. STL的版本3. STL的六大组件4. STL的重要性5. 如何学习STL6. STL的缺陷 1. 什么是STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件…

SkyEye:助力飞行器状态控制系统仿真

飞行器与常见的航天器一样&#xff0c;属于安全关键领域的大型复杂设备&#xff0c;对安全性、可靠性有着极高的要求。为保证稳定飞行&#xff0c;需要对目标对象进行实时跟踪&#xff0c;通过发出正确的修正偏差指令来操纵飞行器改变飞行姿态&#xff0c;因此对飞行器状态控制…

SSM框架,MyBatis-Plus的学习(下)

条件构造器 使用MyBatis-Plus的条件构造器&#xff0c;可以构建灵活高效的查询条件&#xff0c;可以通过链式调用来组合多个条件。 条件构造器的继承结构 Wrapper &#xff1a; 条件构造抽象类&#xff0c;最顶端父类 AbstractWrapper &#xff1a; 用于查询条件封装&#xf…

堆宝塔(Python)

作者 陈越 单位 浙江大学 堆宝塔游戏是让小朋友根据抓到的彩虹圈的直径大小&#xff0c;按照从大到小的顺序堆起宝塔。但彩虹圈不一定是按照直径的大小顺序抓到的。聪明宝宝采取的策略如下&#xff1a; 首先准备两根柱子&#xff0c;一根 A 柱串宝塔&#xff0c;一根 B 柱用于…

python INI文件操作与configparser内置库

目录 INI文件 configparser内置库 类与方法 操作实例 导入INI文件 查询所有节的列表 判断某个节是否存在 查询某个节的所有键的列表 判断节下是否存在某个键 增加节点 删除节点 增加节点的键 修改键值 保存修改结果 获取键值 获取节点所有键值 其他读取方式 …

Python SSH协议库之paramiko使用详解

概要 在网络编程中,远程操作是一项非常常见的需求,特别是在服务器管理和自动化任务执行方面。Python提供了许多库来实现远程操作,其中Paramiko是一个备受欢迎的选择。Paramiko是一个纯Python编写的SSH协议库,它提供了一种简单而强大的方式来执行远程命令、上传和下载文件等…

spring-data-elasticsearch官方文档解读(部分)

Spring Data Elasticsearch 这里主要学习的是4.4.16版本的文档 1. 版本 下表显示了 Spring Data 发行版系列使用的 Elasticsearch 版本和其中包含的 Spring Data Elasticsearch 版本&#xff0c;以及引用该特定 Spring Data 发行版系列的 Spring Boot 版本。给出的 Elastics…

【Spring Boot 3】获取已注入的Bean

【Spring Boot 3】获取已注入的Bean 背景介绍开发环境开发步骤及源码工程目录结构总结 背景 软件开发是一门实践性科学&#xff0c;对大多数人来说&#xff0c;学习一种新技术不是一开始就去深究其原理&#xff0c;而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历…

深入理解Servlet

目录&#xff1a; ServletWeb开发历史Servlet简介Servlet技术特点Servlet在应用程序中的位置Tomcat运行过程Servlet继承结构Servlet生命周期Servlet处理请求的原理Servlet的作用HttpServletRequest对象HttpServletResponse对象ServletContext对象ServletConfig对象Cookie对象与…

面向对象的编程语言是什么意思?——跟老吕学Python编程

面向对象的编程语言是什么意思&#xff1f;——跟老吕学Python编程 面向对象是什么意思&#xff1f;面向对象的定义面向对象的早期发展面向对象的背景1.审视问题域的视角2.抽象级别3.封装体4.可重用性 面向对象的特征面向对象的开发方法面向对象程序设计基本思想实现 面向对象的…

RocketMQ存储设计深度解析

引言 在分布式系统中&#xff0c;消息中间件扮演着至关重要的角色&#xff0c;它负责系统间异步消息的传递&#xff0c;确保信息可靠传输。Apache RocketMQ&#xff08;以下简称RocketMQ&#xff09;是这一领域中的一个优秀代表。RocketMQ以其高性能、高可靠性和高扩展性赢得了…