数据结构——二叉树——堆

 前言:

在前面我们已经学习了数据结构的基础操作:顺序表和链表及其相关内容,今天我们来学一点有些难度的知识——数据结构中的二叉树,今天我们先来学习二叉树中堆的知识,这部分内容还是非常有意思的,下面我们就开始慢慢学习

准备工作:本人习惯将文件放在test.c、SeqList.c、SeqList.h三个文件中来实现,其中test.c用来放主函数,SeqList.c用来放调用的函数,SeqList.h用来放头文件和函数声明

一、什么是树

在正式进行二叉树的学习之前,我们要了解一下树是何物,其实我们经常讲到的计算机中的树其实是以数组的形式存在在内存中的,只是它的可以形象化成树的形状,如下:

如图,其中0所在位置被称为树顶或者树根都可以,下面的称为子树,其中1所在分叉称为左子树,2所在分叉成为右子树

还有一些规则如下:

对于学过离散数学的同学来说这部分知识并不难,没有学过的自己再去搜一下了解一下吧,这里只讲了一些大概内容

二、什么是堆

树里面有几个特殊的概念,例如完全二叉树和满二叉树,而堆就是完全二叉树的一种,完全二叉树就是除了最后一层外,其他层节点数达到最大

堆与普通的完全二叉树的不同在于它的大小堆的性质

大堆:树任何一个父亲>=孩子

小堆:树任何一个父亲<=孩子

例如:

三、堆的节点结构

堆用的顺序表的结构,所以堆的节点结构与顺序表差异不大

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

堆的节点结构很简单,定义一个指针,两个表示容量的整形即可

四、堆的基本操作

//初始化
void HeapInit(HP* php);
//销毁
void HeapDestory(HP* php);
//插入
void HeapPush(HP* php, HPDataType x);
//删除
void HeapPop(HP* php);
//找堆顶元素
HPDataType HeapTop(HP* php);
//判断是否为空
bool HeapEmpty(HP* php);
//算个数
int HeapSize(HP* php);

看上面的函数声明部分我们就可以看到我们每一步要实现的内容,接下来,我们就来一步一步进行实现

1、初始化

//初始化
void HeapInit(HP* php)
{assert(php);php->a = NULL;php->capacity = 0;php->sz = 0;
}

2、销毁

//销毁
void HeapDestory(HP* php)
{free(php->a);free(php);
}

3、插入元素

插入元素时要先检查空间是否够用,如果不够用要先进行扩容

//交换
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 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[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}//插入
void HeapPush(HP* php, HPDataType x)
{assert(php);if (php->sz == php->capacity){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);php->a = tmp;php->capacity = newcapacity;}php->a[php->sz] = x;php->sz++;//向上调整AdjustUp(php->a, php->sz - 1);
}

在这一步我们还创建了几个其他的函数分担一些功能,这些函数在后文中也有应用

4、判断栈顶元素是否为空

这一步在下面有用到,例如当删除树根元素时,如果树根元素为空就无法操作,所以需要判断树根元素是否为空

//判断是否为空
bool HeapEmpty(HP* php)
{assert(php);return php->sz == 0;
}

5、删除元素

这里删除元素是删除树根元素

//删除
void HeapPop(HP* php)
{assert(php);assert(!HeapEmpty(php));Swap(&php->a[0], &php->a[php->sz - 1]);php->sz--;//向下调整AdjustDown(php->a, php->sz,0);
}

6、返回树根元素

//找堆顶元素
HPDataType HeapTop(HP* php)
{assert(php);assert(!HeapEmpty(php));return php->a[0];
}

7、算个数

//算个数
int HeapSize(HP* php)
{assert(php);return php->sz;
}

五、完整代码实例

SeqList.h

typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int sz;int capacity;
}HP;//初始化
void HeapInit(HP* php);
//销毁
void HeapDestory(HP* php);
//插入
void HeapPush(HP* php, HPDataType x);
//删除
void HeapPop(HP* php);
//找堆顶元素
HPDataType HeapTop(HP* php);
//判断是否为空
bool HeapEmpty(HP* php);
//算个数
int HeapSize(HP* php);

test.c

//堆
int main()
{HP hp;HeapInit(&hp);int a[] = { 65,100,70,32,50,60 };for (int i = 0; i < sizeof(a) / sizeof(int); i++){HeapPush(&hp, a[i]);}while (!HeapEmpty(&hp)){int top = HeapTop(&hp);printf("%d ", top);HeapPop(&hp);}return 0;
}

SeqList.c

//堆
//初始化
void HeapInit(HP* php)
{assert(php);php->a = NULL;php->capacity = 0;php->sz = 0;
}
//销毁
void HeapDestory(HP* php)
{free(php->a);free(php);
}
//交换
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 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[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}//插入
void HeapPush(HP* php, HPDataType x)
{assert(php);if (php->sz == php->capacity){int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);php->a = tmp;php->capacity = newcapacity;}php->a[php->sz] = x;php->sz++;//向上调整AdjustUp(php->a, php->sz - 1);
}
//删除
void HeapPop(HP* php)
{assert(php);assert(!HeapEmpty(php));Swap(&php->a[0], &php->a[php->sz - 1]);php->sz--;//向下调整AdjustDown(php->a, php->sz,0);
}
//判断是否为空
bool HeapEmpty(HP* php)
{assert(php);return php->sz == 0;
}
//找堆顶元素
HPDataType HeapTop(HP* php)
{assert(php);assert(!HeapEmpty(php));return php->a[0];
}
//算个数
int HeapSize(HP* php)
{assert(php);return php->sz;
}

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

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

相关文章

前端xss攻击——规避innerHtml过滤标签节点及属性

文章目录 ⭐前言⭐规避innerHtml&#x1f496;在iframe中使用innerHtml的场景&#x1f496;标签转义&#x1f496;url 进行encode&#x1f496;手动过滤内容转义 ⭐inscode代码块演示⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享xss攻击——规避innerHtml过…

list(链表)容器(一)

一、list基本概念 链表&#xff08;list&#xff09;是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的 链表的组成&#xff1a;链表由一系列结点组成 结点的组成&#xff1a;一个是存储数据元素的数据域&#xff0…

通过pymysql读取数据库中表格并保存到excel(实用篇)

本篇文章是通过pymysql将本地数据库中的指定表格保存到excel的操作。 这里我们假设本地已经安装了对应的数据库管理工具&#xff0c;里面有一个指定的表格&#xff0c;现在通过python程序&#xff0c;通过调用pymysql进行读取并保存到excel中。 关于数据库管理工具是Navicat P…

【题解】—— LeetCode一周小结13

【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结12 25.零钱兑换 II 题目链接&#xff1a;518. 零钱兑换 II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合…

NVIDIA Jetson Xavier NX入门-镜像为jetpack5(3)——pytorch和torchvision安装

NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#xff08;3&#xff09;——pytorch和torchvision安装 镜像为jetpack5系列&#xff1a; NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#xff08;1&#xff09;——镜像烧写 NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#…

PI案例分享--2000A核心电源网络的设计、仿真与验证

目录 摘要 0 引言 1 为什么需要 2000A 的数字电子产品? 2 2000A 的供电电源设计 2.1 "MPM3698 2*MPM3699"的 MPS扩展电源架构 2.2 使用恒定导通时间(COT)模式输出核心电压的原因 2.3 模块化 VRM 的优势 2.4 用步进负载验证2000A的设计难点 2.4.1 电源网络 …

机器人---人形机器人之技术方向

1 背景介绍 在前面的文章《行业杂谈---人形机器人的未来》中&#xff0c;笔者初步介绍了人形机器人的未来发展趋势。同智能汽车一样&#xff0c;它也会是未来机器人领域的一个重要分支。目前地球上最高智慧的结晶体就是人类&#xff0c;那么人形机器人的未来会有非常大的发展空…

【深度学习】球衣号码识别 re-id追踪

1. CLIP-ReIdent: Contrastive Training for Player Re-Identification 论文解析–2023的论文&#xff0c;貌似顶会 论文方法是类不可知的&#xff0c;微调CLIP vitl/14模型&#xff0c;在MMSports 2022球员重新识别挑战中实现98.44%的mAP。此外&#xff0c;CLIP Vision Trans…

在 C#和ASP.NET Core中创建 gRPC 客户端和服务器

关于gRPC和Google protobuf gRPC 是一种可以跨语言运行的现代高性能远程过程调用 (RPC) 框架。gRPC 实际上已经成为 RPC 框架的行业标准&#xff0c;Google 内外的组织都在使用它来从微服务到计算的“最后一英里”&#xff08;移动、网络和物联网&#xff09;的强大用例。 gRP…

SQLite3进行数据库各项常用操作

目录 前言1、SQLite介绍2、通过SQLite创建一个数据库文件3、往数据库文件中插入数据4、数据库文件信息查询5、修改数据库中的内容6、删除数据库中的内容 前言 本文是通过轻量化数据库管理工具SQLite进行的基础操作和一些功能实现。 1、SQLite介绍 SQLite是一个广泛使用的嵌入…

微信小程序如何进行npm导入组件

文章目录 目录 文章目录 前言 一、安装node 二、微信小程序通过npm安装组件&#xff08;以Vant-weapp为例&#xff09; 一、Vant-weapp下载 二 、修改 app.json 三 、修改 project.config.json 四 、 构建 npm 包 前言 微信小程序使用npm导入有很多的教程&#xff0c;我…

vue基础教程(5)——十分钟吃透vue路由router

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、路由概念二、路由使用三、创建路由对应的组件四、给整个项目一个入口总结 前言 前面的文章运行成功后&#xff0c;页面显示如下&#xff1a; 在这个页面中&#xff0c;点击Home和About都会切换右面的页面内容&#…

一百以内累加(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS #include <stdio.h>int main() {//初始化变量值&#xff1b;int a 2;int result 1;//循环运算&#xff1b;while (a < 100){//加&#xff1b;result a result;//改变变量值&a…

Spring(详细介绍)

目录 一、简介 1、什么是Spring&#xff1f; 2、Spring框架的核心特性 3、优点 二、IOC容器 介绍 1、获取资源的传统方式 2、控制反转方式获取资源 3、DI 4、IOC容器在Spring中的实现 入门案例 1、创建Maven Module 2、引入依赖 3、创建HelloWorld类 4、在Spring的配…

【动手学深度学习】深入浅出深度学习之利用神经网络识别螺旋状数据集

目录 &#x1f31e;一、实验目的 &#x1f31e;二、实验准备 &#x1f31e;三、实验内容 &#x1f33c;1. 生成螺旋状数据集 &#x1f33c;2. 打印数据集 &#x1f33c;3. 编程实现 &#x1f33b;仿射层-Affine类 &#x1f33b;传播层-Sigmoid类 &#x1f33b;损失函数…

Unity urp渲染管线下,动态修改材质球surfaceType

在项目中遇到了需要代码动态修改材质球的surfaceType&#xff0c;使其动态切换是否透明的需求。 urp渲染管线下&#xff0c;动态修改材质球的surfaceType&#xff0c;查了大部分帖子&#xff0c;都有一些瑕疵&#xff0c;可能会造成透明后阴影投射有问题。 其次在webgl平台上…

简单了解波 Mono-repo Multi-repo(Poly-repo)

Mono-repo 和 Multi-repo 是软件开发中代码管理的两个不同策略。Mono-repo & Multi-repo 孰优孰劣是个老生常谈得话题了&#xff0c;这里就不 PK 了&#xff0c;“略微”看下两者区别。 当我们使用 Git 作为版本控制系统管理项目的代码时&#xff0c;那么 monorepo 与 mul…

iptables 与 firewalld 防火墙

iptables iptables 是一款基于命令行的防火墙策略管理工具 四种防火墙策略&#xff1a; ACCEPT&#xff08;允许流量通过&#xff09; 流量发送方会看到响应超时的提醒&#xff0c;但是流量发送方无法判断流量是被拒绝&#xff0c;还是接收方主机当前不在线 REJECT&#xff08…

上位机图像处理和嵌入式模块部署(qmacvisual寻找圆和寻找直线)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面有几篇文章&#xff0c;我们谈到过直线拟合、圆拟合和椭圆拟合。当时&#xff0c;我们的做法是&#xff0c;先找到了轮廓&#xff0c;接着找到…

设计模式-概述篇

1. 掌握设计模式的层次 第1层&#xff1a;刚开始学编程不久&#xff0c;听说过什么是设计模式第2层&#xff1a;有很长时间的编程经验&#xff0c;自己写了很多代码&#xff0c;其中用到了设计模式&#xff0c;但是自己却不知道第3层&#xff1a;学习过了设计模式&#xff0c;…