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

100.【C语言】数据结构之二叉树的堆实现(顺序结构) 1

目录

1.顺序结构

2.示意图

 ​编辑

从物理结构还原为逻辑结构的方法

3.父子节点编号的规律

4.顺序存储的前提条件

5.堆的简介

堆的定义

堆的两个重要性质

小根堆和大根堆 

6.堆的插入

7.堆的实现及操作堆的函数

堆的结构体定义

堆初始化函数HeapInit

堆插入元素函数HeapPush

堆向上调整函数AdjustUp

写法1

写法2

写法3

提问

向上调整的前提

测试堆插入函数


1.顺序结构

存储二叉树的两种结构:一种顺序结构,一种链式结构本文讲顺序结构


2.示意图

 4311a3c884de4d0caec5b45ef6aa9c66.png

上方图中的数字0~6代表各个节点的编号 

逻辑结构:方便人理解的结构 物理结构:实实在在存储的结构

可见顺序结构的底层是用数组(连续)存储的

从物理结构还原为逻辑结构的方法

对于满二叉树而言,

第一层有一个节点,第二层有两个节点,第一层有四个节点......

则可按层拆分

4f110e1b52564653809e45ad5700440e.png

再组合

aac1aff2adc14578a3eb1be99060ba31.png

加上线

68aacacb93554bda9e40b9e6ea2aa5ee.png

 对于完全二叉树而言,做法和上述类似,不再赘述

3.父子节点编号的规律

比如求F的父节点,如果画图则太慢,其实可以看出规律

F编号为5,其父节点C编号为2;E编号为4,其父节点B编号为1;

发现eq?%5B%5Cfrac%7B5-1%7D%7B2%7D%5D%3D2%2C%5B%5Cfrac%7B4-1%7D%7B2%7D%5D%3D%5B1.5%5D%3D1(注:eq?%5Bx%5D为高斯函数,又称向下取整函数)

★★★求父节点b编号的公式:eq?%5B%5Cfrac%7Bchild-1%7D%7B2%7D%5D%3Dfather

在C语言中为father = (child-1)/2;father获得表达式的商

如果给出父节点的编号,求左孩子和右孩子的编号

父节点C编号为2,则左孩子F的编号为2*2+1,则右孩子G的编号为2*2+2

★★★求孩子节点编号的公式:左孩子:eq?2*father+1  右孩子:eq?2*father+2

4.顺序存储的前提条件

结论:完全二叉树(含满二叉树)适合用顺序存储

25f932f64b0c4f89a726508dbdac504f.png

如果非完全二叉树,存储会浪费空间

5.堆的简介

堆的定义

如果有一个关键码的集合eq?K%20%3D%20%5C%7B%20k_0%2Ck_1%2Ck_2%2C...%2Ck_%7Bn-1%7D%5C%7D,把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:eq?K_i%20%3C%3D%20K_%7B2*i+1%7Deq?K_i%3C%3D%20K_%7B2*i+2%7D%20%28K_i%20%3E%3D%20K_%7B2*i+1%7D%29eq?K_i%20%3E%3D%20K_%7B2*i+2%7D(i=0,1,2,3,..,n)则称为小堆(或大堆)

堆的两个重要性质

  • 堆中某个结点的值总是不大于或不小于其父结点的值;

  • 总是一棵完全二叉树

小根堆和大根堆 

小根堆:树中所有的父节点的值都小于或等于孩子节点的值

大根堆:树中所有的父节点的值都大于或等于孩子节点的值

如果树中所有的父节点的值都等于孩子节点的值,则既为小根堆又为大根堆

注:等定义中并没有规定左孩子和右节点的值的大小关系,因此堆不一定有序

6.堆的插入

由堆的简介可知:堆是一个完全二叉树,因此可以用顺序结构实现

以下方大根堆为例

5516201b19fc4ff4ba832151b1735e7f.jpeg

现要尾插数字20,由存储结构可以看出:空间不够,要扩容

586ea01b4e95478fadf61f4dbb53bc8f.jpeg

插入20前,找其父节点(eq?%5B%5Cfrac%7Bchild-1%7D%7B2%7D%5D%3Dfather),发现后者值为30,可以插入,仍然满足大根堆的性质 

再尾插入60

a761c72718674ece9995f70e1cfc4af1.png

发现不满足大根堆的性质,需要一次调整

4a5e53f5f43649b1a5af1733922837dd.png

发现调整后仍然不满足大根堆的性质(56<60),需要再一次调整 

36899090ed21424586fb62e5227a50d4.png

发现调整后满足大根堆的性质(56<60<70),结束

上述的调整起名为向上调整,最多调整h(二叉树的高度)次

7.堆的实现及操作堆的函数

以大根堆为例

堆的结构体定义

可以用结构体来定义堆,由于堆的底层是用数组存储的,因此三个成员变量:数据域,大小size,容量capacity

写入头文件中

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

堆初始化函数HeapInit

要想使用堆必须先初始化堆(malloc,对size和capacity初始化值)

void HeapInit(HP* php)
{assert(php);php->a = (HPDataType*)malloc(sizeof(HPDataType) * 4);if (php->a == NULL){perror("malloc");return;}php->size = 0;php->capacity = 4;
}

php->capacity跟随malloc函数开辟空间的大小

堆插入元素函数HeapPush

插入前先判断空间是否充足,不够则relloc原来的2倍.之后调用向上调整函数进行插入

void HeapPush(HP* php, HPDataType x)
{assert(php);if (php->size == php->capacity){HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * php->capacity * 2);if (tmp == NULL){perror("realloc");return;}php->a = tmp;php->capacity *= 2;}php->a[php->size] = x;//插入至数组的最后一个元素的下一个位置(size)php->size++;//数组大小+1//调用向上调整函数AdjustUp(php->a,php->size-1);
}

注意到AdjustUp传的第二个参数是php->size-1

堆向上调整函数AdjustUp

如果a[parent] < a[child],则进行交换,之后调整parent和child的值,以便于下一次调整

写法1

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 (a[parent] < a[child]){Swap(&a[parent], &a[child]);//调整parent和child的值child = parent;parent = (parent - 1) / 2;}
}

写法2

void AdjustUp(HPDataType* a, int child)
{int parent = (child - 1) / 2;while (parent>=0){if (a[child] > a[parent]){Swap(&a[parent], &a[child]);child = parent;parent = (parent - 1) / 2;}else{break;}}
}

写法3

void AdjustUp(HPDataType* a, int child)
{int parent = (child - 1) / 2;while (child>0){if (a[child] > a[parent]){Swap(&a[parent], &a[child]);child = parent;parent = (parent - 1) / 2;}else{break;}}
}

提问

已知这几种写法都能成功运行,哪个写法存在不规范的地方?

答:从特殊情况考虑问题,写法2:

当parent==0时,进入循环,若child==1,if判断成立,交换值后,child==0,parent==-1/2==0(取商)

while(parent>=0)条件仍然成立,但不满足if (a[child] > a[parent]),因此break

不规范的地方:child==parent==0就没有必要再次进入循环,建议改成while (child>0)(写法3)

向上调整的前提

除了child位置,前面的数据结构构成堆

测试堆插入函数

main.c手动写入插入一些随机值,以下代码,下断点至return 0;

#include "Heap.h"
int main()
{HP hp;HeapInit(&hp);HeapPush(&hp, 1);HeapPush(&hp, 3);HeapPush(&hp, 0);HeapPush(&hp, 5);HeapPush(&hp, 8);HeapPush(&hp, 12);HeapPush(&hp, 2);HeapPush(&hp, 5);HeapPush(&hp, 30);HeapPush(&hp, 50);return 0;}

打开监视窗口查看

ed16365c491d4a4eb9b111b7b3f5ec30.png

画图后发现符合大根堆的性质

7ab07688e63a4274bcb0527f7b168b07.png

相关文章:

100.【C语言】数据结构之二叉树的堆实现(顺序结构) 1

目录 1.顺序结构 2.示意图 ​编辑 从物理结构还原为逻辑结构的方法 3.父子节点编号的规律 4.顺序存储的前提条件 5.堆的简介 堆的定义 堆的两个重要性质 小根堆和大根堆 6.堆的插入 7.堆的实现及操作堆的函数 堆的结构体定义 堆初始化函数HeapInit 堆插入元素函…...

大模型 VS 大语言模型

最近很多朋友搞不懂大模型和大预言模型的区别&#xff0c;总是把大模型就认为是大语言模型。 今天就用这篇帖子做一个科普。 大模型 概念&#xff1a;大模型是指拥有超大规模参数&#xff08;通常在十亿个以上&#xff09;、复杂计算结构的机器学习模型。它通常能够处理海量数…...

Linux高阶——1117—TCP客户端服务端

目录 1、sock.h socket常用函数 网络初始化函数 首次响应函数 测试IO处理函数 获取时间函数 总代码 2、sock.c SOCKET() ACCEPT()——服务端使用这个函数等待客户端连接 CONNECT()——客户端使用这个函数连接服务端 BIND()——一般只有服务端使用 LISTEN()——服务端…...

【Qt】Qt 在main.cpp中使用tr()函数报错

1. 问题 Qt 在main.cpp中使用tr()报错。 error: tr was not declared in this scope2. 解决方法 main.cpp中注意如下&#xff1a; //添加头文件 #include <QObject>//添加QObject QObject::tr("Hello")3. 参考 Qt tr()函数不起效的小问题...

面向对象高级(5)接口

面向对象高级&#xff08;5&#xff09; 接口 接口就是规范&#xff0c;定义的是一组规则&#xff0c;体现了现实世界中“如果是...则必须能...”的思想。继承是一个"是不是"的is-a关系&#xff0c;而接口实现则是 "能不能"的has-a关系。 1、接口的定义格…...

uniapp发布android上架应用商店权限

先看效果&#xff1a; 实现原理&#xff1a; 一、利用uni.addInterceptor的拦截器&#xff0c;在一些调用系统权限前拦截&#xff0c;进行弹窗展示&#xff0c;监听确定取消实现业务逻辑。 二、弹窗是原生nativeObj进行drawRect绘制的 三、权限申请调用使用的 plus.android.…...

Centos Stream 9安装Jenkins-2.485 构建自动化项目步骤

官网&#xff1a;https://www.jenkins.io/ 1 下载 环境准备&#xff1a; 版本支持查询&#xff1a;https://pkg.jenkins.io/redhat-stable/ 安装JDK17&#xff1a;https://blog.csdn.net/qq_44870331/article/details/140784297 yum -y install epel-release wget upgradew…...

电路模型和电路定理(二)

电路元件 是电路中最基本的组成单元。 电阻元件&#xff1a;表示消耗电能的元件 电感元件&#xff1a;表示产生磁场&#xff0c;储存磁场能的元件 电容元件&#xff1a;表示产生电场&#xff0c;储存电场能量的元件 电压源和电流源&#xff1a;表示将其他形式的能量转变成…...

瑞佑液晶控制芯片RA6807系列介绍 (三)软件代码详解 Part.10(让PNG图片动起来)完结篇

RA6807是RA8876M的缩小版&#xff0c;具备RA8876M的所有功能&#xff0c;只将MCU控制接口进行缩减&#xff0c;仅保留SPI-3和I2C接口&#xff0c;其它功能基本相同。 该芯片最大可控制854x600的分辨率&#xff0c;内建64Mbits显存&#xff0c;多个图层&#xff0c;使用起来相当…...

Qt常用控件 按钮

文章目录 1. QAbstractButton 简介2. QPushButton2.1 例子1&#xff0c;设置按钮的图标2.2 例子2&#xff0c;设置按钮快捷键 3. QRadioButton3.1 介绍3.2 例子1&#xff0c;选择性别3.3 例子2&#xff0c;试试其他的信号3.3 例子3&#xff0c;分组 4. QCheckBox4.1 介绍4.2 例…...

MySQL学习/复习10视图/用户/权限/语言连接数据库

一、视图 1.1创建视图 1.2视图影响基表 1.3基表影响视图 1.4删除视图 1.5视图使用规则 二、数据库的用户 2.1mysql中的user表 注意事项&#xff1a;主机/用户名/密码/权限 2.2用户的创建 注意事项&#xff1a;设置密码与登录地点需谨慎 2.3删除用户 注意事项&#xff1a;% 2.4…...

vulfocus在线靶场:tomcat-pass-getshell 弱口令 速通手册

目录 一、启动环境&#xff0c;访问页面&#xff0c;并登录&#xff0c;账号密码都是tomcat 二、哥斯拉打war包&#xff0c;图解 三、上传war包&#xff0c;图解 四、访问我们直接url/木马文件名/木马文件.jsp&#xff0c;是否存在了 五、 哥斯拉测试连接结果success&…...

c#:winform调用bartender实现打印(学习整理笔记)

效果 学习路径 C# winform调用Bartender进行自定义打印、批量打印、检索文件夹中的模板_哔哩哔哩_bilibili 一、初始环境搭建见&#xff1a; c#:winform引入bartender-CSDN博客https://blog.csdn.net/weixin_46001736/article/details/143989473?sharetypeblogdetail&s…...

牛客题库 21738 牛牛与数组

牛牛与数组题目链接 题目大意 牛牛喜欢这样的数组: 1:长度为n 2:每一个数都在1到k之间 3:对于任意连续的两个数A,B,A<=B 与(A % B != 0) 两个条件至少成立一个请问一共有多少满足条件的数组,对 1 e 9 + 7 1e^9+7 1e9+7 取模 输入格式 输入两个整数 n , k n,k n,…...

探索PDFMiner:Python中的PDF解析利器

文章目录 **探索PDFMiner&#xff1a;Python中的PDF解析利器**1. 背景介绍&#xff1a;为何选择PDFMiner&#xff1f;2. PDFMiner是什么&#xff1f;3. 如何安装PDFMiner&#xff1f;4. 简单库函数使用方法4.1 提取文本4.2 获取页面布局信息4.3 提取表格数据4.4 提取图像 5. 应…...

掌握Go语言中的异常控制:panic、recover和defer的深度解析

掌握Go语言中的异常控制:panic、recover和defer的深度解析 在Go语言的编程世界中,异常处理是一个不可忽视的话题。Go语言提供了panic、recover和defer三个关键字来处理程序中的异常情况。本文将深入探讨这三个关键字的工作原理、使用场景和最佳实践,帮助读者在实际编程中更…...

云讷科技Kerloud无人飞车专利发布

云讷科技Kerloud无人飞车获得了“一种室内外两用的四旋翼无人飞车”的实用新型专利证书&#xff0c;作为科教社区第一款四旋翼飞车&#xff0c;这项技术结合了无人机和无人车的优势&#xff0c;提供了一种能够在多种环境下使用的多功能飞行器。 这项设计的优势如下&#xff…...

企业信息化-走进身份管理之搭建篇

​一、身份管理是什么 我们先要弄懂统一身份管理到底是什么&#xff1f; 统一身份管理&#xff08;Unified Identity Manager&#xff0c;UIM&#xff09;&#xff0c;身份管理&#xff08;Identity Management&#xff0c;简称IDM&#xff09;&#xff0c;也被称为IAM&#…...

实践指南:EdgeOne与HAI的梦幻联动

在当今快速发展的数字时代&#xff0c;安全和速度已成为网络服务的基石。EdgeOne&#xff0c;作为腾讯云提供的边缘安全加速平台&#xff0c;以其全球部署的节点和强大的安全防护功能&#xff0c;为用户提供了稳定而高效的网络体验。而HAI&#xff08;HyperApplicationInventor…...

Exploring Prompt Engineering: A Systematic Review with SWOT Analysis

文章目录 题目摘要简介方法论背景相关工作评估结论 题目 探索快速工程&#xff1a;基于 SWOT 分析的系统评价 论文地址&#xff1a; https://arxiv.org/abs/2410.12843 摘要 在本文中&#xff0c;我们对大型语言模型 (LLM) 领域的提示工程技术进行了全面的 SWOT 分析。我们强…...

ByteBuffer 与 ByteBuf 的对比与优缺点分析

在 Java 网络编程和高性能 I/O 场景中&#xff0c;ByteBuffer 和 ByteBuf 是两种重要的缓冲区处理工具。ByteBuffer 是 Java NIO 标准库的一部分&#xff0c;而 ByteBuf 是由 Netty 框架提供的增强缓冲区工具。在实际开发中&#xff0c;选择哪一种取决于场景需求和性能目标。 …...

js高级06-ajax封装和跨域

8.1、ajax简介及相关知识 8.1.1、原生ajax 8.1.1.1、AJAX 简介 AJAX 全称为 Asynchronous JavaScript And XML&#xff0c;就是异步的 JS 和 XML。 通过 AJAX 可以在浏览器中向服务器发送异步请求&#xff0c;最大的优势&#xff1a;无刷新获取数据。 按需请求&#xff0c;可…...

RabbitMQ3:Java客户端快速入门

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…...

D 型 GaN HEMT 在功率转换方面的优势

氮化镓 (GaN) 是一种 III-V 族宽带隙半导体&#xff0c;由于在用作横向高电子迁移率晶体管 (HEMT) 时具有卓越的材料和器件性能&#xff0c;因此在功率转换应用中得到越来越多的采用。 HEMT 中产生的高击穿电场 (3.3 MV/cm) 和高二维电子气 (2DEG) 载流子迁移率 (2,000 cm 2 /…...

Java Web后端项目的特点和组成部分

技术栈 #### Java Web技术&#xff1a; - **Servlet**&#xff1a;Java Web的核心&#xff0c;用于处理HTTP请求。 - **WebServlet注解配置**&#xff1a;用于简化Servlet的配置。 - **HttpServlet基类**&#xff1a;大多数Servlet都继承自此基类。 - **请求响应处理**&#x…...

Vue3 + Vite + TS 项目引入 Eslint + Pritter

文章目录 一、ESLint 简介主要功能适用场景常用的 Eslint 配置项 二、Pritter 简介主要功能适用场景常用的 Prettier 配置项 三、Vue3 Vite TS 项目引入 Eslint Pritter1. 安装 ESLint2. 初始化 ESLint 配置3. 在 Vite 项目中启用 ESLint4. 在 VS Code 中启用 ESLint5. 集成…...

用Tauri框架构建跨平台桌面应用:1、Tauri快速开始

Tauri 是一个构建适用于所有主流桌面和移动平台的轻快二进制文件的框架。开发者们可以集成任何用于创建用户界面的可以被编译成 HTML、JavaScript 和 CSS 的前端框架&#xff0c;同时可以在必要时使用 Rust、Swift 和 Kotlin 等语言编写后端逻辑。 Tauri 是什么&#xff1f; |…...

Django实现智能问答助手-数据库方式读取问题和答案

扩展 增加问答数据库&#xff0c;通过 Django Admin 添加问题和答案。实现更复杂的问答逻辑&#xff0c;比如使用自然语言处理&#xff08;NLP&#xff09;库。使用前端框架&#xff08;如 Bootstrap&#xff09;增强用户界面 1.注册模型到 Django Admin&#xff08;admin.py…...

stm32利用LED配置基础寄存器+体验滴答定时器+hal库环境配置

P1 LED控制与流水灯效果实现 概述 大家好&#xff0c;今天我们来学习一下如何在STM32上控制LED灯&#xff0c;并且实现一个流水灯的效果。这不仅是一个基础的实践&#xff0c;也是嵌入式开发中非常常见的需求。 LED控制 1. LED初始化 首先&#xff0c;我们需要对LED灯对应…...

JAVA开源项目 桂林旅游景点导游平台 计算机毕业设计

博主说明&#xff1a;本文项目编号 T 079 &#xff0c;文末自助获取源码 \color{red}{T079&#xff0c;文末自助获取源码} T079&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…...