堆的实现(偷懒版)

🌹个人主页🌹:喜欢草莓熊的bear
🌹专栏🌹:数据结构

目录
前言
一、堆的实现
1.1 堆的向下调整算法
思路:
1.2 堆的向上调整算法
1.3 堆的创建
1.4 堆的复杂度计算
向下调整建堆的复杂度:
向上调整建堆的复杂度:
1.5 堆的插入
1.6 堆的删除
1.7 堆的代码实现
总结
前言
在上期内容介绍了二叉树、还简单提了一下堆的概念和大堆、小堆。回顾一下堆是首先是完全二叉树,因为是完全二叉树所以使用数组储存比较合理。
一、堆的实现
1.1 堆的向下调整算法
int arr[] = {27,15,19,18,28,34,65,49,25,37}; 
上面这幅图就是向下调整的算法的过程图
思路:
假设我们通过向下调整算法建立小堆,我们就需要从根的左右子树开始,比较得出左右子树小的那一个和根比较,谁小谁就是根。我们之前还介绍父亲节点和孩子节点的概念,我们这里就要使用到。根据我们上面的思路,向下调整算法需要通过比较还在节点后进行调整。所以我们需要知道父亲节点然后再找到孩子节点为什么要知道父亲节点呢?我们通过数组储存着堆,下标就可以帮助我们找到孩子节点。

大致思路就是这样我们来写代码:
void Swap(HPDataType* x, HPDataType* y)//交换数据
{HPDataType tmp = *x;*x = *y;*y = tmp;
}void ADjustDown(HPDataType* a, int n,int parent)//向下调整
{int child = parent * 2 + 1;while (child < n){//假设法if (a[child] > a[child + 1] && child + 1 < n)//比较左右子树,找到较小的子树。{child++;}if (a[parent] > a[child])//数据交换{Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}
解释一下个别代码,child + 1 < n 防止数组越界。
1.2 堆的向上调整算法

向上调整我们需要从最后一层向上调整,所以我们是通过孩子节点得到父亲节点。大致思路和向下调整一样,比较孩子节点的大小后再和父亲节点比较一直比较到根节点。根据child = parent *2+1 反推得到 parent = ( child -1 )/2 。
直接上代码:
void Swap(HPDataType* x, HPDataType* y)//交换数据
{HPDataType tmp = *x;*x = *y;*y = 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;}}
}
1.3 堆的创建
int a[] = {1,5,3,8,7,6}; 
1.4 堆的复杂度计算
向下调整建堆的复杂度:
向上调整建堆的复杂度:
是O(N) = N * logN 得到方法和向下调整一样推导就可以了。
1.5 堆的插入
堆的插入需要用的向上调整
1.6 堆的删除
1.7 堆的代码实现
堆的初始化、销毁都是很简单和之前写的栈啊等等都十分相似。剩下一些 获取堆顶元素、堆的个数、堆的判断都比较简单就不讲解了给上了代码。
typedef int HPDataType;typedef struct Heap//因为堆的定义就是满二叉树与完全二叉树,用数组储存非常好。
{HPDataType* a;//数组int size;int capacity;
}Heap;//小堆情况下的初始化
void HPInit(Heap* php)
{assert(php);php->a = NULL;php->size = php->capacity = 0;
}//销毁
void HPDestory(Heap* php)
{assert(php);free(php->a);php->a = NULL;php->size = php->capacity = 0;
}void Swap(HPDataType* x, HPDataType* y)//交换数据
{HPDataType tmp = *x;*x = *y;*y = 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 ADjustDown(HPDataType* a, int n,int parent)//向下调整
{int child = parent * 2 + 1;while (child < n){//假设法if (a[child] > a[child + 1] && child + 1 < n){child++;}if (a[parent] > a[child]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}//入堆
void HPPush(Heap* php, HPDataType x)
{assert(php);//扩容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("ralloc fail");return;}php->a = tmp;php->capacity = Newcapacity;}php->a[php->size++] = x; ADjustUp(php->a,php->size - 1);
}//出堆(消除堆顶数据)
void HPPop(Heap* php)
{assert(php);assert(php->size > 0);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;ADjustDown(php->a,php->size,0);
}//取堆顶数据
HPDataType HPTop(Heap* php)
{assert(php);assert(php->size > 0);return php->a[0];
}//堆的数据个数
int HPSize(Heap* php)
{assert(php);return php->size;
}//堆的判空
bool HPEmpty(Heap* php)
{assert(php);return php->size == 0;
}
总结
本节重点堆的向上、向下调整算法的代码实现 和 复杂度计算。
相关文章:
堆的实现(偷懒版)
🌹个人主页🌹:喜欢草莓熊的bear 🌹专栏🌹:数据结构 目录 前言 一、堆的实现 1.1 堆的向下调整算法 思路: 1.2 堆的向上调整算法 1.3 堆的创建 1.4 堆的复杂度计算 向下调整建堆的复杂度…...
一键启动,智能分拣:3D视觉系统赋能多SKU纸箱高效混拆作业
在快速发展的电商时代,仓储物流面临着前所未有的挑战。尤其是面对成千上万种不同的纸箱,如何实现快速、准确、高效的混拆作业,成为了众多企业亟待解决的问题。幸运的是,随着科技的进步,3D视觉系统正逐步成为这一领域的…...
unity草体渲染方案 GPU Instaning
有一天看项目里的FrameDebug发现在森林系的场景里草体的drawcall差不多有100多 主要是因为灯光贴图,位置等不一样导致的打断合批,导致一个批次只能渲染10个左右的草体 之前有了解过unity有接口(Graphics.DrawMeshInstanced)可以把…...
最近在西安召开的学术会议:EI检索超快,信息系统与计算技术领域!
第十二届信息系统与计算技术国际会议(ISCTech 2024)将于2024年11月8日-11月11日在中国西安盛大举行,由长沙理工大学主办,同济大学、西北工业大学联合协办。会议聚焦信息系统与计算技术等相关研究领域,广泛邀请国内外知…...
sRGB和伽马矫正
sRGB和伽马矫正 1. sRGB的含义: sRGB是一种色彩空间,全称为“标准红色-绿色-蓝色”(standard Red Green Blue)。它由惠普和微软在1996年共同开发,用于确保不同设备上色彩的一致性。 在sRGB中,“s”代表“…...
Summer School science communication project--Laptop Selection Suggestion
目录 Introduction Audiance Usage CPU What is a central processing unit (CPU) Notable makers of CPUs GPU Graphics Card: GPU The classifications of graphics cards The brands of graphics cards Dedicated Graphics Cards GeForce MX Series: GeForc…...
网络编程概念详解模拟回显客户端服务器
目录 1.网络中重要的概念 1)IP地址: 2)端口号: 3)协议 协议分层 OSI七层模型(教科书) TCP/IP五层模型 封装和分用 网络套接字 面试题:TCP/UDP的区别? UDP数据报套接字编程 模拟一个回…...
代码随想录第二十四天|动态规划(8)
目录 LeetCode 300. 最长递增子序列 LeetCode 674. 最长连续递增序列 LeetCode 718. 最长重复子数组 LeetCode 1143. 最长公共子序列 LeetCode 1035. 不相交的钱 LeetCode 53. 最大子序和 LeetCode 392. 判断子序列 总结 LeetCode 300. 最长递增子序列 题目链接&#…...
编程-设计模式 3:单例模式
设计模式 3:单例模式 定义与目的 定义:单例模式确保一个类只有一个实例,并提供一个全局访问点来访问该实例。目的:这种模式通常用于那些需要频繁访问且只需一个实例的对象,例如配置管理器、日志记录器等。 实现示例…...
Kaniko 构建 Docker 镜像
Kaniko 主要用于构建 Docker 镜像,而不是运行程序。它的主要用途是从 Dockerfile 构建容器镜像,但它并不负责运行容器或程序。以下是 Kaniko 的主要功能和局限性: 主要功能 构建镜像:Kaniko 从 Dockerfile 构建容器镜像。它通过…...
Javascript常见算法(每日两个)
合并两个有序链表 在JavaScript中,合并两个有序链表通常指的是将两个已经按照某种顺序(如升序或降序)排列的链表合并成一个新的有序链表。由于JavaScript本身不直接支持链表数据结构,我们通常会用对象或数组来模拟链表的行为。但…...
Spring -- 事务
Spring中事务的操作分为两类:(1)编程式事务 – 手动写代码操作事务(2)声明式事务 – 利用注解开启事务和提交事务 1. 编程式事务 准备Controller RestController RequestMapping("/user") public class UserInfoController {Autowiredprivate UserInfoService use…...
生命密码的破译者:AI如何学会读懂DNA语言?
引言 如果能像解读一本神秘的书籍那样,理解DNA的“语言”,将是多么令人兴奋的科学突破!如今,这正在逐步变为现实。科学家们训练出的AI模型GROVER正如一个勤奋的学生,学习着DNA的每一个“单词”和“语法”,…...
大数据信用报告查询哪家平台的比较好?
相信在搜索大数据信用的你,已经因为大数据信用不好受到了挫折,想详细了解一下自己的大数据信用,但是找遍了网络上的平台之后才发现,很多平台都只提供查询服务,想要找一个专业的平台查询和讲解很困难。下面本文就为大家…...
Java高级Day24-集合最后补充
75.HashTable 基本介绍: 存放元素的健值对 即K-V hashtable的键和值都不能为null,否则会抛出NullPointerException hashtable使用方法基本上和HashMap一样 hashtable是线程安全的,hashmap是线程不安全 扩容机制: 底层有数组…...
C++入门:C语言到C++的过渡
前言:C——为弥补C缺陷而生的语言 C起源于 1979 年,当时 Bjarne Stroustrup 在贝尔实验室工作,面对复杂软件开发任务,他感到 C 语言在表达能力、可维护性和可扩展性方面存在不足。 1983 年,Bjarne Stroustrup 在 C 语言…...
了解MVCC
概念 MVCC,全称Multi-Version Concurrency Control,即多版本并发控制,是一种并发控制的方法,维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现…...
WPF自定义控件的应用(DynamicResource的使用方法)
1 DynamicResource的使用方法 可以在字典文件 的抬头区写入数: <SolidColorBrush x:Key"PrimaryBackgroundColor" Color"#FFABAdB3"/><SolidColorBrush x:Key"TextBox.MouseOver.Border" Color"#FF7EB4EA"/>&l…...
Postgresql数据库密码忘记的解决
当您忘记PostgreSQL数据库的密码时,可以通过以下步骤来重置密码。这些步骤在Windows和Linux操作系统上大体相同,但具体操作路径和命令可能有所不同。 步骤一:找到并修改pg_hba.conf文件 定位安装目录: Windows:通常在PostgreSQL的安装目录下的data文件夹中。Linux:位置可…...
Flink SQL 基础操作
Flink SQL是建立在Apache Flink之上的SQL处理引擎,它允许用户以SQL的方式处理流数据和批数据。以下是一些Flink SQL的基础操作: 一、环境准备 1.启动flink集群 ./start-cluster.sh启动sql-client ./sql-client.sh二、数据源定义 创建表(…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
