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

【数据结构】堆的向上调整和向下调整以及相关方法

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃

文章目录

  • 一、堆的概念
  • 二、堆的性质
  • 三、堆的分类
    • 1.大根堆
    • 2.小根堆
  • 四、说明
  • 五、堆的结构
  • 🚩六、堆的向上调整
    • 1.图示
    • 2.代码实现
    • ⌚️3.时间复杂度分析
  • 📌七、堆的向下调整
    • 1.思路:
    • 2.代码实现
    • ⌚️3.时间复杂度分析
  • 八、删除根
    • 1.思路:
    • 2.代码实现
    • ⌚️3.时间复杂度分析
  • 九、创建堆
    • 1.思路:
    • 2.代码实现
  • 十、所有方法实现汇总

一、堆的概念

堆(Heap)是计算机科学中一类特殊的数据结构的统称。如果有一个关键码的集合K = { , , ,…, },把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足: <= 且 <= ( >= 且 >= ) i = 0,1, 2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。除了最后一层以外上面的节点但是非空的,最后一层节点是从左到右依次排布的)

二、堆的性质

🔸 非线性,完全二叉树。适合用数组存储。
🔸堆是无序的,也就是左右可以互换
🔸最值总在 0 号位
根据这个特点我们就可以做很多事情,比如TopK问题 (在一堆数据里面找到前 K 个最大 / 最小的数).
比如点餐软件中有上千家店铺,我想选出该地区好评最多的十家川菜店,我们不用对所有数据排序,只需要取出前 K 个最大 / 最小数据。使用堆排序效率也更高。

三、堆的分类

1.大根堆 2.小根堆

1.大根堆

定义:树中的任意一个双亲节点都大于等于孩子节点。
在这里插入图片描述

2.小根堆

定义:树中的任意一个双亲节点都小于等于孩子节点。

在这里插入图片描述

四、说明

以下的方法均以小堆来推理,如果想实现大堆,则修改【<】符号等方式实现。

五、堆的结构

typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;

🚩六、堆的向上调整

向上调整的前提是,调整位置之前必须是堆。如果目的是调成小堆,则要保证调整位置之前是小堆;如果目的是调成大堆,则要保证调整位置之前是大堆。

1.图示

在这里插入图片描述

2.代码实现

//向上调整
void AdjustUp(HPDataType* a, int child)
{//传入数组,child为孩子节点下标int parent = (child - 1) / 2;//当一直交换到根,停止while (child>0){if (a[parent] > a[child]){Swap(&a[parent], &a[child]);child = parent;parent = (child - 1) / 2;}elsereturn;}
}

⌚️3.时间复杂度分析

时间复杂度:O(logN)
最坏情况:调整到根;
最好情况:不用调整,

📌七、堆的向下调整

向下调整的前提是,左右子树必须是小堆或者大堆。

1.思路:

如图:
此案例是要调整根节点40开始向下调整,首先确保根节点的左右子树是小堆(由图得成立)。
1.parent的两个孩子进行比较,选出小的。
2.进行交换
3.child>n结束
在这里插入图片描述

2.代码实现

//向下调整
void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;//一直交换到数的最后,也就是数组的最后一个位置while (parent<n){if (child + 1 < n && a[child + 1] < a[child]){child++;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);// 继续往下调整parent = child;child = parent * 2 + 1;}else{return;}}
}

⌚️3.时间复杂度分析

时间复杂度:O(logN)
最坏情况:调整到根;
最好情况:不用调整,

八、删除根

1.思路:

1.先将根与最后一个节点交换,
2.删除最后一个节点;
3.进行向下调整。

在这里插入图片描述

2.代码实现

void HeapPop(HP* p)
{assert(p);assert(p->size > 0);Swap(&p->a[0], &p->a[p->size - 1]);--p->size;AdjustDown(p->a, p->size, 0);
}

⌚️3.时间复杂度分析

时间复杂度:O:N(logN)

九、创建堆

创建堆的思路可以通过向上调整,也可通过向下调整。这里讲通过向上调整建立堆。
由于我的AdjustUp函数是用来调整小堆的,所以,这里创建的也是小堆。

1.思路:

传入参数
a:数组,n:是数组元素个数
1.为p->a开辟n个空间;
2.利用memcpy函数,把数组a复制到p->a中
3.在使用AdjustUp调整,从1-n-1逐步向下延伸;
在这里插入图片描述
在这里插入图片描述

2.代码实现

//建立小堆
void HeapInitArray(HP* p, int* a, int n)
{//a:数组,n:是数组元素个数assert(p);assert(a);p->a = (HPDataType*)malloc(sizeof(HPDataType) * n);if (p->a == NULL){perror("malloc fail");exit(-1);}p->size = n;p->capacity = n;//把传入数组a复制到p->a中memcpy(p->a, a, sizeof(HPDataType) * n);// 向上调整,调整成一个小堆for (int i = 1; i < n; i++){AdjustUp(p->a, i);}
}

十、所有方法实现汇总

#define _CRT_SECURE_NO_WARNINGS 1
#include"Heap.h"//初始化
void HeapInit(HP* p)
{assert(p);p->a = NULL;p->size = 0;p->capacity = 0;
}//销毁
void HeapDestroy(HP* p)
{assert(p);free(p->a);p->a = NULL;p->size = p->capacity = 0;
}//插入数据
void HeapPush(HP* p, HPDataType x)
{//从最后一个位置插入assert(p);//扩容if (p->capacity == p->size){//如果刚开始数组为空,就开辟4个空间。如果不为空,以后每次扩大2倍。int newcapacity = p->capacity==0 ? 4 : p->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(p->a, sizeof(HPDataType) * p->capacity);if (tmp == NULL){perror("realloc fial\n");exit(-1);}p->a = tmp;p->capacity = newcapacity;}p->a[p->size] = x;p->size++;AdjustUp(p->a, p->size-1);
}//交换
void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}//向上调整
void AdjustUp(HPDataType* a, int child)
{//传入数组,child为孩子节点下标int parent = (child - 1) / 2;//当一直交换到根,停止while (child>0){if (a[parent] > a[child]){Swap(&a[parent], &a[child]);child = parent;parent = (child - 1) / 2;}elsereturn;}
}//向下调整
void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;//一直交换到数的最后,也就是数组的最后一个位置while (parent<n){if (child + 1 < n && a[child + 1] < a[child]){child++;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);// 继续往下调整parent = child;child = parent * 2 + 1;}else{return;}}
}//打印二叉树
void HeapPrint(HP* php)
{assert(php);for (size_t i = 0; i < php->size; i++){printf("%d ", php->a[i]);}printf("\n");
}//建立小堆
void HeapInitArray(HP* p, int* a, int n)
{//a:数组,n:是数组元素个数assert(p);assert(a);p->a = (HPDataType*)malloc(sizeof(HPDataType) * n);if (p->a == NULL){perror("malloc fail");exit(-1);}p->size = n;p->capacity = n;//把传入数组a复制到p->a中memcpy(p->a, a, sizeof(HPDataType) * n);// 向上调整,调整成一个小堆for (int i = 1; i < n; i++){AdjustUp(p->a, i);}
}//删除根
void HeapPop(HP* p)
{assert(p);assert(p->size > 0);Swap(&p->a[0], &p->a[p->size - 1]);--p->size;AdjustDown(p->a, p->size, 0);
}
//获取根
HPDataType HeapTop(HP* p)
{assert(p);assert(p->size > 0);return p->a[0];
}//判空
bool HeapEmpty(HP* p)
{assert(p);return p->size == 0;
}

相关文章:

【数据结构】堆的向上调整和向下调整以及相关方法

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3; 文章目录 一、堆的概念二、堆的性质…...

【蓝桥杯选拔赛真题60】Scratch旋转风车 少儿编程scratch图形化编程 蓝桥杯选拔赛真题解析

目录 scratch旋转风车 一、题目要求 编程实现 二、案例分析 1、角色分析...

JavaSE、JavaEE与Spring的概念和异同点剖析以及规范13 个分析

JavaSE、JavaEE与Spring的概念和异同点剖析以及规范13 个分析 目录概述需求&#xff1a; 设计思路实现思路分析1.什么是JavaSE2.是JavaEE3.什么是Spring 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&…...

微信小程序的图书馆图书借阅 座位预约系统 读者端设计与实现

该系统基于B/S即所谓浏览器/服务器模式&#xff0c;应用springboot框架&#xff0c;选择MySQL作为后台数据库。系统主要包括系统图书信息、图书借阅、图书归还、自习室信息、自习室预约等功能模块。 关键词 微信小程序的图书馆读者端&#xff1b;微信小程序&#xff1b;java语…...

在阿里云 linux 服务器上查看当前服务器的Nginx配置信息

我们可以通过命令 sudo nginx -t查看到nginx.conf的路径 可以通过 sudo nginx -T查看 nginx 详细配置信息&#xff0c;包括加载的配置文件和配置块的内容 其中也会包括配置文件的内容...

专业招投标书翻译怎样做比较好

在全球经济贸易一体化不断深入的时代&#xff0c;招投标作为国际通用的新型贸易方式&#xff0c;受到了大量中外企业的青睐。根据国际惯例&#xff0c;与招标采购活动有关的一切文件资料&#xff0c;均须使用英文编制。即使允许使用非英文语言编制&#xff0c;也必须随附一份英…...

算法总结10 线段树

算法总结10 线段树 线段树2569. 更新数组后处理求和查询 线段树 有一个数组&#xff0c;我们要&#xff1a; 更新数组的值&#xff08;例如&#xff1a;都加上一个数&#xff0c;把子数组内的元素取反&#xff09;查询一个子数组的值&#xff08;例如&#xff1a;求和&#x…...

518抽奖软件,支持按人像照片抽奖

518抽奖软件简介 518抽奖软件&#xff0c;518我要发&#xff0c;超好用的年会抽奖软件&#xff0c;简约设计风格。 包含文字号码抽奖、照片抽奖两种模式&#xff0c;支持姓名抽奖、号码抽奖、数字抽奖、照片抽奖。(www.518cj.net) 照片抽奖模式 圆角边框 照片抽奖模式下&am…...

数字IC笔试面试题之--时钟偏斜(skew)与抖动(jitter)

1 时钟偏斜&#xff08;clock skew&#xff09; 时钟偏斜&#xff08;偏移&#xff09;是因为布线长度和负载不同&#xff0c;导致同一时钟上升沿到不同触发器的时间不同。这一时间差&#xff0c;即为时钟偏移。 时钟偏斜可能导致时序违例&#xff08;本文直接粘贴了参考博客…...

免费api接口:物流api,企业工商查询api,游戏api。。。

免费api接口&#xff0c;物流api,企业工商查询api,游戏api。。。都有。 Facebook Games Services - Facebook Games Services 为游戏开发者提供了各种服务, 包括(但不限于) 成就 API, 分数 API, 应用通知, 请求, 游戏养成和 Facebook SDK for Unity.Google Play Games Service…...

第二十八章 Classes - 引用其他类的方法

文章目录 第二十八章 Classes - 引用其他类的方法引用其他类的方法对当前实例的引用 第二十八章 Classes - 引用其他类的方法 引用其他类的方法 在方法(或例程)中&#xff0c;使用下面的语法来引用其他类中的方法: 要调用类方法并访问其返回值&#xff0c;请使用如下表达式:…...

Android 中集成 TensorFlow Lite图片识别

在上图通过手机的相机拍摄到的物体识别出具体的名称&#xff0c;这个需要通过TensorFlow 训练的模型引用到项目中&#xff1b;以下就是详细地集成 TensorFlow步骤&#xff0c;请按照以下步骤进行操作&#xff1a; 在项目的根目录下的 build.gradle 文件中添加 TensorFlow 的 Ma…...

NSSCTF之Misc篇刷题记录(16)

NSSCTF之Misc篇刷题记录&#xff08;16&#xff09; [黑盾杯 2020]encrypt[UTCTF 2020]Spectre[UTCTF 2020]Observe closely NSSCTF平台&#xff1a;https://www.nssctf.cn/ PS&#xff1a;所有FLAG改为NSSCTF [黑盾杯 2020]encrypt UTAxSlUwTkRWRVo3Um1GclpWOWxibU55ZVhCMGFX…...

域名解析--nslookup和dig

dig (Domain Information Groper) dig 是一个功能强大且更灵活的 DNS 查询工具&#xff0c;通常在 Linux 和 macOS 等 Unix-like 操作系统上使用。以下是 dig 的一些常见用法和区别&#xff1a; 查询域名信息 dig example.com这将返回与指定域名相关的 DNS 记录&#xff0c;…...

EXCEL如何把一个单元格内的文本和数字分开?例如:龚龚15565 = 龚龚 15565

使用工具&#xff1a;WPS 举例&#xff1a; EXCEL如何把一个单元格内的文本和数字批量分开&#xff1f;不使用数据分列。 第一步、将第二行数据冻结 第二步、在B1、C1单元格输入需要分开的示例 第三步、点击选中B1单元格&#xff0c;输入快捷键【CTRLE】进行填充。B2单元格也是…...

uniapp抽取组件绑定事件中箭头函数含花括号无法解析

版本: "dcloudio/uni-ui": "^1.4.27", "vue": "> 2.6.14 < 2.7"... 箭头函数后含有花括号的时候, getData就拿不到val参数 , 解决办法就是去除花括号 // 错误代码: <SearchComp change"(val) > { getData({ val …...

猫头虎博主第四期赠书活动:《精通Go语言:(第2版) 》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

【学习总结】EasyExcel合并同列不同行,表格数据相同的行

实体类 Data HeadRowHeight(50) ContentStyle(horizontalAlignment HorizontalAlignmentEnum.CENTER, verticalAlignment VerticalAlignmentEnum.CENTER, wrapped BooleanEnum.TRUE) public class CriterionDataExportDTO {ColumnWidth(15)ExcelProperty(value "所属…...

Tokenview X-ray功能:深入探索EVM系列浏览器的全新视角

Tokenview作为一家领先的多链区块浏览器&#xff0c;为了进一步优化区块链用户的使用体验&#xff0c;我们推出了X-ray&#xff08;余额透视&#xff09;功能。该功能将帮助您深入了解EVM系列浏览器上每个地址的交易过程&#xff0c;以一种直观、简洁的方式呈现地址的进出账情况…...

【洛谷 P1364】医院设置 题解(图论+深度优先搜索)

医院设置 题目描述 设有一棵二叉树&#xff0c;如图&#xff1a; 其中&#xff0c;圈中的数字表示结点中居民的人口。圈边上数字表示结点编号&#xff0c;现在要求在某个结点上建立一个医院&#xff0c;使所有居民所走的路程之和为最小&#xff0c;同时约定&#xff0c;相邻接…...

攻克Atlas OS中Xbox应用登录错误0x89235107的完整方案

攻克Atlas OS中Xbox应用登录错误0x89235107的完整方案 【免费下载链接】Atlas &#x1f680; An open and lightweight modification to Windows, designed to optimize performance, privacy and security. 项目地址: https://gitcode.com/GitHub_Trending/atlas1/Atlas …...

ollama-QwQ-32B模型微调:提升OpenClaw任务执行准确率的实战方法

ollama-QwQ-32B模型微调&#xff1a;提升OpenClaw任务执行准确率的实战方法 1. 为什么需要微调模型来优化OpenClaw 上周三凌晨3点&#xff0c;我被一阵刺耳的提示音惊醒——OpenClaw又闯祸了。它本应自动整理我的项目文档&#xff0c;却误删了3个关键文件夹&#xff0c;还把桌…...

SpringBoot集成gRPC踩坑指南:从.proto文件到服务调用的完整流程

SpringBoot与gRPC深度整合实战&#xff1a;从协议定义到生产级部署 在微服务架构盛行的今天&#xff0c;跨语言服务调用已成为刚需。作为Google开源的RPC框架&#xff0c;gRPC凭借其基于HTTP/2的高效传输和Protocol Buffers的紧凑序列化&#xff0c;在分布式系统中展现出独特优…...

总结各GPU的OpenCL子组洗牌支持情况

penCL 2.0 通过扩展cl_khr_subgroups提供一些基础子组操作支持&#xff0c;包括获取子组 ID、组内 ID 等基本功能&#xff0c;组内断言(any/all)、广播(broadcast)、归约(reduce)、扫描(scan)等基本操作&#xff0c;同时允许一些可选扩展支持更丰富的子组操作&#xff08;比如洗…...

高维问题如何“降维计算”:矩阵映射、卷积与拆分汇总

你在课程里提到一个很重要的工程化思想&#xff1a; 高维问题看起来复杂&#xff0c;但很多计算可以通过“拆分再计算”的方式降维处理 这篇把它整理成一条可复述的主线&#xff0c;重点放在&#xff1a; 为什么能拆拆完怎么汇总和矩阵/卷积的关系是什么 先说明一个常见误解&am…...

Win11Debloat:3步让你的Windows 11系统重获新生

Win11Debloat&#xff1a;3步让你的Windows 11系统重获新生 【免费下载链接】Win11Debloat 一个简单的PowerShell脚本&#xff0c;用于从Windows中移除预装的无用软件&#xff0c;禁用遥测&#xff0c;从Windows搜索中移除Bing&#xff0c;以及执行各种其他更改以简化和改善你的…...

深度学习计算机视觉:从原理到实践

深度学习计算机视觉&#xff1a;从原理到实践 1. 背景与动机 计算机视觉是深度学习最成功的应用领域之一。从图像分类到目标检测&#xff0c;从语义分割到图像生成&#xff0c;深度学习技术已广泛应用于自动驾驶、医疗影像、工业检测等领域。本文将介绍计算机视觉的核心技术和实…...

WechatDecrypt终极指南:3步轻松解密微信数据库的完整方案

WechatDecrypt终极指南&#xff1a;3步轻松解密微信数据库的完整方案 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 想要找回珍贵的聊天记录却苦于微信加密机制&#xff1f;WechatDecrypt作为一款专业的…...

无网环境下的containerd部署实战:从静态二进制到服务就绪

1. 为什么需要离线部署containerd&#xff1f; 在工业控制、军工系统、金融核心业务等特殊场景中&#xff0c;服务器往往运行在物理隔离的网络环境中。我曾经参与过一个智能制造项目&#xff0c;生产线的控制服务器连内网都不允许接入&#xff0c;更别说访问互联网了。这种环境…...

Linux系统auditd审计服务实战:从零配置到规则优化(附常用命令大全)

Linux系统auditd审计服务实战&#xff1a;从零配置到规则优化&#xff08;附常用命令大全&#xff09; 当服务器遭遇入侵时&#xff0c;大多数管理员的第一反应往往是查看历史命令记录。但现实情况是&#xff0c;黑客通常会第一时间清空.bash_history文件。这时&#xff0c;一个…...