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

堆的基本实现

一、堆的概念

在提出堆的概念之前,首先要了解二叉树的基本概念

一颗二叉树是节点的有限集合,该集合:

1、或者为空;

2、或者由一个根节点加上两颗分别称为左子树和右子树的两颗子树构成;

 堆就是一颗完全二叉树;

堆有两种:小堆和大堆

堆在内存上的存储是数组形式的(物理结构);我们认为想象成链式结构(逻辑结构)

通过数组结构去实际存储,有这样的规律:每个父节点的下标乘以2加1就是左孩子节点,加2就是右孩子节点;无论是左孩子还是右孩子,其下标减去1再 /2 就是父节点的下标,这就是通过数组存储堆(完全二叉树)的优点。


 

 二、堆实现的相关头文件

#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
#include<stdlib.h>
#include<errno.h>
//堆有两种:大堆、小堆
typedef int HPDataType;typedef struct Heap
{HPDataType* arr;int size;int capacity;
}Heap;//堆的构建
void HeapInit(Heap* php);//堆的销毁
void HeapDestroy(Heap* php);//向上调整
void AdjustUp(Heap* php, int child);
//堆的插入
void HeapPush(Heap* php, HPDataType x);//向下调整
void AdjustDown(Heap* php, int parent, int size);
//堆的删除
void HeapPop(Heap* php);//取出堆顶的数据
HPDataType HeapTop(Heap* php);//堆的数据个数
int HeapSize(Heap* php);//堆的判空
bool HeapEmpty(Heap* php);

堆是完全二叉树,所以用数组存储可以方便访问子节点和父节点;


三、堆基本接口的实现(大堆)

1、堆的构建(初始化)

void HeapInit(Heap* php)
{assert(php);php->arr = NULL;php->size = php->capacity = 0;
}

2、堆的销毁

//堆的销毁
void HeapDestroy(Heap* php)
{assert(php);if (php->arr == NULL){free(php->arr);}php->arr = NULL;php->size = php->capacity = 0;
}

3、堆的插入

void HeapPush(Heap* php, HPDataType x)
{assert(php);if (php->size == php->capacity){int newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;HPDataType* tmp = (HPDataType*)realloc(php->arr,sizeof(HPDataType) * newcapacity);if (tmp == NULL){perror("realloc failed");exit(1);}php->arr = tmp;php->capacity = newcapacity;}php->arr[php->size++] = x;//向上调整AdjustUp(php->arr,php->size-1);
}

堆只有大堆和小堆之分,插入数据和顺序表一样,关键是插入数据之后要对数组里面的数据进行调整;

插入数据用到向上调整

//向上调整
void AdjustUp(HPDataType* arr,int child)
{int parent = (child - 1) / 2;while (child>0){if (arr[child] > arr[parent]){//交换数组里面的值Swap(&arr[child], &arr[parent]);//继续比较大小要将child和parent的值向上移动child = parent;parent = (child - 1) / 2;}else{//之前的数据都是一个一个建好的大堆//父节点的值比子节点的大,停止break;}}
}
void Swap(HPDataType* x, HPDataType* y)
{HPDataType tmp = *x;*x = *y;*y = tmp;
}

每次插入进堆的数据都是孩子节点(形参名称),向上调整的原因就是每个子树的父亲节点理论上是要大于孩子节点的,但是插入的数据可能要比父节点大,所以在向上调整函数里面要先通过孩子节点的下标找到对应的父节点,之后再比较看是否要交换,直到父亲节点大于子节点;

循环结束的条件是child>0,当child为0的时候说明已经调整到根节点的位置了。

4、堆的删除

//堆的删除
void HeapPop(Heap* php)
{assert(php && php->size>0);//删除是删除的是堆顶的数据,若是直接让数组整体往前移动 堆被打乱 要重新建堆 时间复杂度高;//方法:交换堆首位的数据,让size--,再从堆顶开始向下调整Swap(&php->arr[0],& php->arr[php->size - 1]);php->size--;AdjustDown(php->arr, 0, php->size - 1);
}

堆的删除删除的是根节点的数据,也就是数组里面下标为0的数据;如果直接移动数组下标删除,那么新数组就不再是一个堆,此时要重新建堆,代价过大;

采用这种方式:每次进行删除之前先交换堆首尾的数据,之后再让size--,就访问不到原来的根节点,此时得到的新数组,除了根节点处的数据,它的子树都是大堆;此时进行向下调整算法,把这个不应该是根节点的数据向下调整,把下面的数据里面最大的调整到根节点处;

向下调整算法

void AdjustDown(HPDataType* arr, int parent, int size)//size指向的是最后一个有效数据
{int child = parent * 2 + 1;//定义为左孩子while (child <= size){if (child+1<=size && arr[child] < arr[child + 1])//当最后一个子树只有左孩子时,child+1越界{child = child + 1;//若是右孩子较大,那么就定义成右孩子}//总是大的调到上面去if (arr[child] > arr[parent]){Swap(&arr[child], &arr[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

向下调整是从下标为0处开始调整的,这个0下标位置就是父节点,通过乘以2加上1的办法找到子节点,但是要找到子节点里面较大的那个所以上面代码就有了child处和child+1处数据大小的比较,若是父节点小于子节点就交换;每次调整完都刷新父节点和子节点的下标,以便一直往下面调整直到父节点的数据要大于子节点的数据就停止;

循环结束的条件是child<size,这里的size是数组里面最后一个有效数的下标;

5、堆顶数据、堆的数据个数、堆的判空

//取出堆顶的数据
HPDataType HeapTop(Heap* php)
{assert(php && php->size>0);return php->arr[0];
}//堆的数据个数
int HeapSize(Heap* php)
{assert(php);return php->size;
}//堆的判空
bool HeapEmpty(Heap* php)
{assert(php);return php->size == 0;
}

相关文章:

堆的基本实现

一、堆的概念 在提出堆的概念之前&#xff0c;首先要了解二叉树的基本概念 一颗二叉树是节点的有限集合&#xff0c;该集合&#xff1a; 1、或者为空&#xff1b; 2、或者由一个根节点加上两颗分别称为左子树和右子树的两颗子树构成&#xff1b; 堆就是一颗完全二叉树&…...

Ubuntu上编译多个版本的frida

准备工作 Ubuntu20(WSL) 略 安装依赖 sudo apt update sudo apt-get install build-essential git lib32stdc-9-dev libc6-dev-i386 -y nodejs 去官网[1]下载nodejs&#xff0c;版本的话我就选的20.15.1&#xff1a; tar -xf node-v20.15.1-linux-x64.tar.xz 下载源码 …...

概率论三大分布

目录 基本概念 卡方分布&#xff08;χ分布&#xff09;&#xff1a; t分布&#xff1a; F分布&#xff1a; 延伸 卡方分布在哪些具体情况下最适合用于数据分析&#xff1f; t分布在大样本情况下的表现与正态分布相比如何&#xff1f; F分布在进行方差比较时与t分布的区…...

Spring系统学习-基于XML的声明式事务

基本概念 在Spring框架中&#xff0c;基于XML的事务管理是一种通过XML配置文件来管理事务的方式。Spring提供了强大的事务管理功能&#xff0c;可以与多种持久化技术&#xff08;如JDBC、Hibernate、JPA等&#xff09;结合使用。以下是如何在Spring中使用基于XML的事务管理的基…...

iOS中的MVVM设计模式

目录 前言 一、MVVM简介 二、MVVM的核心思想 三、MVVM的优势 四、MVVM在iOS中的实现 1. 创建Model 2. 创建ViewModel 3. 创建View 4. 主入口 总结 前言 随着iOS开发的发展&#xff0c;构建可维护和可扩展的代码架构变得至关重要。Model-View-ViewModel (MVVM) 是一种…...

ES中的数据类型学习之ARRAY

Arrays | Elasticsearch Guide [7.17] | Elastic 中文翻译 &#xff1a;Array Elasticsearch 5.4 中文文档 看云 Arrays In Elasticsearch, there is no dedicated array data type. Any field can contain zero or more values by default, however, all values in the a…...

vue网络请求

post网络请求 import axios from axios import {ElMessage, ElLoading} from "element-plus" import { nextTick } from "vue" import JSONbig from json-bigint import { userToken } from "/constants/Constant.js";const defaultConfig {bas…...

几何光学基本原理——费马原理和射线方程

在几何光学中&#xff0c;射线方程用于描述光在折射率不均匀的介质中传播的路径。折射率的变化会导致射线发生弯曲&#xff0c;射线方程正是用于计算这种弯曲路径的。 几何光学的基本原理 几何光学假设光在介质中沿直线传播&#xff0c;但在折射率变化的介质中&#xff0c;光的…...

OpenCV车牌识别技术详解

第一部分&#xff1a;图像预处理 车牌识别&#xff08;License Plate Recognition&#xff0c;LPR&#xff09;是计算机视觉领域的一个重要应用&#xff0c;它涉及到图像处理、模式识别等多个方面。OpenCV作为一个强大的计算机视觉库&#xff0c;提供了丰富的车牌识别相关功能…...

解决llama_index中使用Ollama出现timed out 问题

现象&#xff1a; File "~/anaconda3/envs/leo_py38/lib/python3.8/site-packages/httpx/_transports/default.py", line 86, in map_httpcore_exceptionsraise mapped_exc(message) from exc httpx.ReadTimeout: timed out代码&#xff1a; from llama_index.core …...

Python爬虫技术 第14节 HTML结构解析

HTML 结构解析是 Web 爬虫中的核心技能之一&#xff0c;它允许你从网页中提取所需的信息。Python 提供了几种流行的库来帮助进行 HTML 解析&#xff0c;其中最常用的是 BeautifulSoup 和 lxml。 1. 安装必要的库 首先&#xff0c;你需要安装 requests&#xff08;用于发送 HTT…...

【vue3|第18期】Vue-Router路由的三种传参方式

日期:2024年7月17日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.408…...

ElasticSearch(六)— 全文检索

一、match系列查询 前面讲到的query中的查询&#xff0c;都是精准查询。可以理解成跟在关系型数据库中的查询类似。match系列的查询&#xff0c;是全文检索的查询。会通过分词进行评分&#xff0c;匹配&#xff0c;再返回搜索结果。 1.1 match 查询 "query": {&qu…...

Oracle核心进程详解并kill验证

Oracle核心进程详解并kill验证 文章目录 Oracle核心进程详解并kill验证一、说明二、核心进程详解2.1.PMON-进程监控进程2.2.SMON-系统监控进程2.3.DBWn-数据库块写入进程2.4. LGWR-日志写入器进程2.5. CKPT-检查点进程 三、Kill验证3.1.kill ckpt进程3.2.kill pmon进程3.3.kill…...

【BUG】已解决:SyntaxError:positional argument follows keyword argument

SyntaxError:positional argument follows keyword argument 目录 SyntaxError:positional argument follows keyword argument 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c…...

怎样在 Nginx 中配置基于请求客户端 Wi-Fi 连接状态的访问控制?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; 文章目录 怎样在 Nginx 中配置基于请求客户端 Wi-Fi 连接状态的访问控制一、理解请求客户端 Wi-Fi 连接状态二、Nginx 中的访问控制基础知识三、获取客户端 Wi-Fi 连接状态…...

逆向案例二十九——某品威客登录,请求头参数加密,简单webpack

网址&#xff1a;登录- 一品威客网,创新型知识技能共享服务平台 抓到登陆包分析&#xff0c;发现请求头有参数加密&#xff0c;直接搜索 定位到加密位置&#xff0c;打上断点&#xff0c;很明显是对象f的a方法进行了加密。 往上找f&#xff0c;可以发现f被定义了&#xff0c;是…...

河道高效治理新策略:视频AI智能监控如何助力河污防治

一、背景与现状 随着城市化进程的加快&#xff0c;河道污染问题日益严重&#xff0c;对生态环境和居民生活造成了严重影响。为了有效治理河道污染&#xff0c;提高河道管理的智能化水平&#xff0c;TSINGSEE青犀提出了一套河污治理视频智能分析及管理方案。方案依托先进的视频…...

[React]如何提高大数据量场景下的Table性能?

[React]如何提高大数据量场景下的Table性能&#xff1f; 两个方向&#xff1a;虚拟列表&#xff0c;发布订阅 虚拟列表 虚拟列表实际上只对可视区域的数据项进行渲染 可视区域&#xff08;visibleHeight&#xff09;: 根据屏幕可视区域动态计算或自定义固定高度数据渲染项&…...

基于Vision Transformer的mini_ImageNet图片分类实战

【图书推荐】《PyTorch深度学习与计算机视觉实践》-CSDN博客 PyTorch计算机视觉之Vision Transformer 整体结构-CSDN博客 mini_ImageNet数据集简介与下载 mini_ImageNet数据集节选自ImageNet数据集。ImageNet是一个非常有名的大型视觉数据集&#xff0c;它的建立旨在促进视觉…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...