数据结构——lesson8二叉树的实现

💞💞 前言

hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
在这里插入图片描述

💥个人主页:大耳朵土土垚的博客
💥 所属专栏:数据结构学习笔记
💥对于数据结构顺序表、链表、堆有疑问的都可以在上面数据结构的专栏进行学习哦~ 有问题可以写在评论区或者私信我哦~

前面我们学习过二叉树的前、中、后序遍历 以及二叉树层序遍历,今天我们将继续学习有关二叉树的实现🥳🥳🥳

1.二叉树的构建

1.1二叉树的结构

typedef char BTDataType;//这里使用字符类型方便看下面的ABC等字母
//typedef int BTDataType;其他我们使用int
typedef struct BinaryTreeNode
{BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;//二叉树的结构

二叉树每个节点应该包含该节点的值,以及其左右子节点的地址

1.2创建二叉树新节点

//创建新节点
BTNode* BuyNode(BTDataType x)
{BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));if (newnode == NULL){perror("malloc fail");return NULL;}newnode->data = x;return newnode;
}

使用malloc函数创建节点,最后销毁时要使用free来释放,malloc大小为BTNode的节点;
对于mallc函数有疑问的可以查看土土的博客——动态内存函数介绍;

1.3创建二叉树

以数组"ABD##E#H##CF##G##"为例

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{if(a[*pi] == '#'){(*pi)++;return NULL;}BTNode* root = BuyNode(a[*pi]);(*pi)++;root->left = BinaryTreeCreate(a, pi);root->right = BinaryTreeCreate(a, pi);return root;
}

利用监视进行可视化如下:
在这里插入图片描述

在这里插入图片描述
可以看到形成了逻辑结构如下图所示的二叉树:
在这里插入图片描述

我们将这里的’#'当作空的标志,用来实现二叉树的结构,并利用递归左子树右子树来构建二叉树。

2.二叉树的销毁

// 二叉树销毁
void BinaryTreeDestroy(BTNode* root)
{if (root == NULL)return;//类似于后序,先释放左右子树再释放根节点BinaryTreeDestroy(root->left);BinaryTreeDestroy(root->right);free(root);
}

这里二叉树的销毁需要对二叉树进行遍历,我们前面学习过四种二叉树的遍历——前、中、后序以及层序遍历,对于销毁二叉树来说使用后序遍历比较合适,因为先释放左右子树再释放根节点这样可以防止找不到节点。

3.二叉树节点个数

// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{/*if (root == NULL)return 0;return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;*/return root == NULL ? 0 : BinaryTreeSize(root->left)+ BinaryTreeSize(root->right) + 1;
}

如果节点是空就返回,不是空就继续递归找其左子树右子树直到找到空也就是叶子节点的左右子树,此时再递归返回叶子节点的父节点时要+1,用来表示计算的叶子节点;依次类推不是NULL就+1,这样最后就是二叉树节点的个数了;图解如下:
以下图为例:
在这里插入图片描述
1.找到NULL:
在这里插入图片描述返回左右子树为空后要+1;
2.依次类推递归返回:
在这里插入图片描述
在这里插入图片描述

也可以看下面的递归展开图:
以下图为例:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4.二叉树叶子节点个数

// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{if (root == NULL)return 0;//叶子节点if (root->left == NULL && root->right == NULL)return 1;return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

叶子节点对应其左右子树都为空,就返回1,利用递归实现

5.二叉树第k层节点个数

// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{assert(k);if(root == NULL)return 0;//k层节点个数if (k == 1)return 1;return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

我们可以利用k-1依次往下递归,直到k = 1 时此时,就是第k层就返回1;

6.二叉树查找

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if (root == NULL)return NULL;//前序遍历来查找if (root->data == x){return root;}BTNode* res1 = BinaryTreeFind(root->left, x);if (res1)return res1;BTNode* res2 = BinaryTreeFind(root->right, x);if (res2)return res2;//没有找到返回空return NULL;
}

在运用递归时要返回值时记得将递归找到的值保存起来,防止找不到耗费力气重新再找。

7.二叉树高度

//求二叉树高度
int BTreeHeight(BTNode* root)
{if (root == NULL)return 0;int leftHeight = BTreeHeight(root->left);int rightHeight = BTreeHeight(root->right);return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}

类似于二叉树节点个数的递归,返回时每次+1,并且我们还需要将每次计算的高度与二叉树查找一样保存起来防止浪费时间再去遍历查找,此外左子树右子树高度不一致时要取较大的那一个;

8.判断是否是完全二叉树

在此之前我们先回顾一下特殊的二叉树:

1. 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是2^k - 1 ,则它就是满二叉树。
2. 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
要注意的是满二叉树是一种特殊的完全二叉树。
在这里插入图片描述

这里判断是否为完全二叉树的实现与之前讲过的二叉树层序遍历相似需要利用队列来实现,队列的实现在这——二叉树层序遍历里面包含队列代码的完整实现,这里就不过多描述,我们直接来使用。记得使用时要先写队列并包含对应的头文件哦~

// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{//利用队列先进先出的特点Queue qt;QueueInit(&qt);if (root)//如果根节点非空则入队列QueuePush(&qt, root);while (!QueueEmpty(&qt))//判断队列非空{QDataType front = QueueFront(&qt);//取出队头元素QueuePop(&qt);if (front == NULL)break;//遇到空就跳出QueuePush(&qt, front->left);//再将左右子树的节点入队列QueuePush(&qt, front->right);}//break跳出后//判断之后的元素是否有非空值//有非空值则不是完全二叉树while (!QueueEmpty(&qt)){QDataType front = QueueFront(&qt);QueuePop(&qt);if (front != NULL){QueueDestroy(&qt);return false;}}//如果没有非空值返回trueQueueDestroy(&qt);return true;
}

思路:利用二叉树的层序遍历,层序遍历一遍如果有空指针NULL且队列非空时如果队列里面还有非空值那么就不是完全二叉树。

9.结语

以上就是有关二叉树实现的内容啦 ~ 关键是要理解递归是怎么实现的,利用二叉树由根节点、左右子树构成的特性来实现递归,完结撒花 ~🥳🥳🎉🎉🎉

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

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

相关文章

【玩转pandas系列】pandas数据结构—DataFrame

文章目录 前言一、DataFrame创建1.1 字典创建1.2 NumPy二维数组创建 二、DataFrame切片2.1 行切片2.2 列切片2.3 行列切片 三、DataFrame运算3.1 DataFrame和标量的运算3.2 DataFrame之间的运算3.3 Series和DataFrame之间的运算 四、DataFrame多层次索引4.1 多层次索引构造1.隐…

软考高级:架构描述语言 ADL 概念和例题

作者:明明如月学长, CSDN 博客专家,大厂高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

【Linux】Ubuntu使用Netplan配置静态/动态IP

1、说明 Ubuntu 18.04开始,Ubuntu和Debian移除了以前的ifup/ifdown命令和/etc/network/interfaces配置文件,转而使用ip link set或者/etc/netplan/01-netcfg.yaml模板和sudo netplan apply命令实现网络管理。 Netplan 是抽象网络配置描述器,用于配置Linux网络。 通过netpla…

旧华硕电脑开机非常慢 电脑开机黑屏很久才显示品牌logo导致整体开机速度非常的慢怎么办

前提条件 电池需要20%(就是电池没有报废)且电脑接好电源,千万别断电,电脑会变成砖头的 解决办法 更新bios即可解决,去对应品牌官网下载最新的bios版本就行了 网上都是一些更新驱动啊

【Godot4.2】颜色完全使用手册

概述 本篇简单汇总Godot中的颜色的构造和使用,内容包括了: RGB、RGBA,HSV以及HTML16进制颜色值、颜色常量等形式构造颜色颜色的运算以及取反、插值用类型化数组、紧缩数组或PNG图片形式存储多个颜色 构造颜色 因为颜色是一种视觉元素&…

8-图像缩放

其实,就是开辟一个zoomwidth,zoomheight的内存,再分别赋值即可。 void CDib::Scale(float xZoom, float yZoom) { //指向原图像指针 LPBYTE p_data GetData(); //指向原像素的指针 LPBYTE lpSrc; //指向缩放图像对应像素的指针 LPBYTE lpDs…

基于grafana+elk等开源组件的 云服务监控大屏架构

本套大屏,在某云服务大规模测试环境,良好运行3年. 本文主要展示这套监控大屏的逻辑架构.不做具体操作与配置的解释. 监控主要分为三部分: 数据展示部分数据存储数据采集 1. 数据展示 数据展示方面主要使用grafana 2. 数据存储 根据数据种类和特性和用途的不同,本套监控采用…

Mysql的行级锁

MySQL 中锁定粒度最小的一种锁,是 针对索引字段加的锁 ,只针对当前操作的行记录进行加锁。 行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。行级锁和存…

Vue项目的搭建

Node.js 下载 Node.js — Download (nodejs.org)https://nodejs.org/en/download/ 安装 测试 winR->cmd执行 node -v配置 在安装目录下创建两个子文件夹node_cache和node_global,我的就是 D:\nodejs\node_cache D:\nodejs\node_global 在node_global文件下再创建一个…

ArkTS 基础组件

目录 一、常用组件 二、文本显示(Text/Span) 2.1 创建文本 2.2 属性 2.3 添加子组件(Span) 2.4 添加事件 三、按钮(Button) 3.1 创建按钮 3.2 设置按钮类型 3.3 悬浮按钮 四、文本输入(TextInput/TextArea)…

Flask学习(四):路由转换器

默认的路由转换器&#xff1a; string &#xff08;缺省值&#xff09; 接受任何不包含斜杠的文本int接受正整数float接受正浮点数 path类似 string&#xff0c;但可以包含斜杠uuid接受 UUID 字符串 代码示例&#xff1a; app.route(/user/<username>) def show_u…

2024 年(第 12 届)“泰迪杯”数据挖掘挑战赛——B 题:基于多模态特征融合的图像文本检索完整思路与源代码分享

一、问题背景 随着近年来智能终端设备和多媒体社交网络平台的飞速发展&#xff0c;多媒体数据呈现海量增长 的趋势&#xff0c;使当今主流的社交网络平台充斥着海量的文本、图像等多模态媒体数据&#xff0c;也使得人 们对不同模态数据之间互相检索的需求不断增加。有效的信…

【GPT-SOVITS-06】特征工程-HuBert原理

说明&#xff1a;该系列文章从本人知乎账号迁入&#xff0c;主要原因是知乎图片附件过于模糊。 知乎专栏地址&#xff1a; 语音生成专栏 系列文章地址&#xff1a; 【GPT-SOVITS-01】源码梳理 【GPT-SOVITS-02】GPT模块解析 【GPT-SOVITS-03】SOVITS 模块-生成模型解析 【G…

大数据 - Spark系列《十四》- spark集群部署模式

Spark系列文章&#xff1a; 大数据 - Spark系列《一》- 从Hadoop到Spark&#xff1a;大数据计算引擎的演进-CSDN博客 大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置-CSDN博客 大数据 - Spark系列《三》- 加载各种数据源创建RDD-CSDN博客 大数据 - Spark系列《…

《前端系列》之前端学习路线

目录 1 前言2 前端学习路线2.1 入门阶段2.1.1 HTML2.1.2 CSS2.1.3 JavaScript2.1.4 网络基础 2.2 基础阶段2.2.1 前端框架2.2.2 深入JavaScript2.2.3 ES62.2.4 工程化知识 2.3 进阶阶段2.3.1 CSS2.3.2 Javascript2.3.3 单元测试2.3.4 性能优化 3 总结 1 前言 在技术更新迭代发…

Python数学建模-2.5Pandas库介绍

2.5.1Pandas基本操作 Pandas是一个强大的Python数据分析库&#xff0c;它提供了快速、灵活且富有表现力的数据结构&#xff0c;设计初衷是为了处理关系型或标记型数据。Pandas的基本操作涵盖了数据的读取、处理、筛选、排序、分组、合并以及可视化等多个方面。 以下是一些Pan…

【从零开始学习数据结构 | 第一篇】树

目录 前言&#xff1a; 树&#xff1a; 树结点之间的关系描述&#xff1a; 树的常见属性&#xff1a; 森林&#xff1a; ​编辑树的性质&#xff1a; 总结&#xff1a; 前言&#xff1a; 当谈论数据结构时&#xff0c;树&#xff08;Tree&#xff09;是一种极为重要且常…

测试人员Bug书写规范

&#x1f4cb; 个人简介 作者简介&#xff1a;大家好&#xff0c;我是凝小飞&#xff0c;软件测试领域作者支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 在测试人员日常工作中&#xff0c;关于bug的编写和定义是一个比较经常的工作&#xff0c;如果bug编写描…

在Linux/Ubuntu/Debian中使用7z压缩和解压文件

要在 Ubuntu 上使用 7-Zip 创建 7z 存档文件&#xff0c;你可以使用“7z”命令行工具。 操作方法如下&#xff1a; 安装 p7zip&#xff1a; 如果你尚未在 Ubuntu 系统上安装 p7zip&#xff08;7-Zip 的命令行版本&#xff09;&#xff0c;你可以使用以下命令安装它&#xff1a;…

研究生总结

Note:本博客更多是关于自己的感悟&#xff0c;没有翻阅文件详细查证&#xff0c;如果存在错过&#xff0c;也请提出指正。 1. 半监督回归 相比于半监督分类&#xff0c;半监督回归相对冷门。回归和分类之间有着难以逾越的天谴&#xff0c;预测精度。分类中的类别是可数的&…