【二叉树】——链式结构(快速掌握递归与刷题技巧)

📙作者简介: 清水加冰,目前大二在读,正在学习C/C++、Python、操作系统、数据库等。

📘相关专栏:C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。

欢迎点赞 👍 收藏 ⭐留言 📝 如有错误还望各路大佬指正!

✨每一次努力都是一种收获,每一次坚持都是一种成长✨       

在这里插入图片描述

目录

 前言

1. 二叉树的链式结构

   1.1链式二叉树的结构

2. 二叉树初阶训练

 2.1 二叉树节点个数

 2.2 叶子节点个数

 2.3 第k层节点个数

总结


 前言

        前边我主要介绍了二叉树的顺序结构,链式结构也只是简单提及,今天我们来详细介绍一下二叉树的链式结构。


1. 二叉树的链式结构

        二叉树的顺序结构是通过顺序表来存储二叉树的数据,那么链式结构就是通过链表,连接二叉树的各个节点,进而来实现二叉树的树形结构。链式二叉树存储不需要像堆那要必须是完全二叉树,它可以是一颗普通二叉树。 

   1.1链式二叉树的结构

        二叉树的链式结构是指使用节点之间的指针连接来表示二叉树的结构。在链式结构中,每个节点都包含一个数据元素和指向其左子节点和右子节点的指针。一个二叉树的节点通常由两个部分组成:数据域和指针域。

typedef struct BinaryTree
{int data;//数据域struct BinaryTree* left;//指针域struct BinaryTree* right;//指针域
}BTNode;

         通过这种链式结构,我们可以方便地遍历和操作二叉树。最常见的遍历方法就是使用递归遍历二叉树。前边我们也简单介绍了二叉树的前序、中序、后续遍历。也很简单,但是在实际中,并不会这么直白的让你递归遍历二叉树,都是遍历的变形。

2. 二叉树初阶训练

 2.1 二叉树节点个数

   如何计算一个二叉树的节点个数呢?

  链式结构的树使用递归来遍历最简单,也是最常用的遍历方法。这样写吗?

int TreeSize(BTNode* root)
{int size = 0;if (root == NULL)return 0;else++size;TreeSize(root->left);TreeSize(root->right);return size;
}

         节点是NULL就返回0,不为空就size++。看似没有问题,但深入思考一下就会发现端倪,每次递归都会重新创建一个size然后++,每次的size都加到了一个size上吗?其实并没有,size出了函数作用域就会销毁,递归到叶子节点返回后,前边的size就会被销毁。

         只要解决size作用域问题是不是就可以解决了?增加size的生命周期有两种方法,一个是使用全局变量,另一个是使用static修饰。这样虽然可以计算出二叉树的节点个数,但这样也存在缺点,这个函数的使用就会变成一次性的,如果在一个程序中多次调用,数据就会累计(如第一次是5,第二次就是10……),也有解决的办法就是每次使用前将size置为0。但这都不是这个问题的最优解,最优解就是使用递归解决。

        递归的核心就是分治,将一个复杂的过程分解成一个一个的类似子问题。要计算一颗二叉树的节点个数就只需要计算左子树节点个数+右子树节点个数+1。左子树又可以分为左子树右子树,直到叶子节点,叶子节点的左右子树为NULL,所以遇到NULL就返回0;那我们就可以这样写:

int TreeSize(BTNode* root)
{if (root == NULL)return 0;return TreeSize(root->left) + TreeSize(root->right) + 1;
}

 如下图:

         虚线代表的递归返回,返回节点的个数。这里也仅仅是一个简单的递归,有了这个题目的思路,我们来进阶一下。

 2.2 叶子节点个数

        计算叶子节点个数也是使用递归,对这个问题进行分治,计算一棵树的叶子节点个数,也就是左子树和右子树中叶子节点的个数,子树又可以再分为左子树、右子树。遇到叶子节点就停止。使用递归可以大幅的减少代码的复杂度。现在就只需考虑一下递归停止的条件。叶子节点的左子树与右子树都为空,所有当根的左右子树都为NULL时就可以判定为叶子节点。

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);
}

  例如这棵树,有三个叶子节点:

         当前节点为NULL就不是叶子节点返回0,如果左右子树都为NULL,则该节点就是叶子节点,返回1,最后将左子树和右子树的叶子节点个数相加,最终返回值就是叶子节点的个数。

 2.3 第k层节点个数

         在前两个的基础上我们再来一个变形,计算第k层节点个数。这道题目不像前两个那要,它需要有控制一下递归的深度。

int BinaryTreeLevelKSize(BTNode* root, int k)

        传入一个k,和根节点,通过k来控制递归的深度。这里我们默认根节点的高度是1。如果遇到NULL就返回0;

int BinaryTreeLevelKSize(BTNode* root, int k)
{assert(k > 0);if (root == NULL){return 0;}if (k == 1){return 1;}return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);    
}

例如这棵树:

         假设我们要计算第3层节点个数。第一次调用从根开始,k此时等于3,然后开始向下递归第二次调用,传参是k-1,到第二层时k=2,到第三层时,k=1。这里我们需要注意一下两个判断返回的顺序,要先判断当前节点是否为NULL,不为NULL才开始判断k是否为1。


总结

         本篇文章主要简单介绍了一下二叉树的链式结构,以及链式结构遍历的特点,通过一些简单的练习帮助大家更快上手二叉树的链式递归。理解并使用好递归的分治,对于后续的学习至关重要,希望这篇文章可以帮到您。最后,感谢阅读!

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

《学术小白学习之路12》进阶-基于Python实现中文文本的DTM主题动态模型构建

《学术小白学习之路》基于Python实现中文文本的DTM主题动态模型构建 一、数据选择二、数据预处理三、输入数据ID映射词典构建四、文档加载成构造语料库五、DTM模型构建与结果分析六、结果进行保存七、保存模型一、数据选择 所选取的数据集是论文摘要,作为实验数据集,共计12条…

基于微信小程序的校园代送跑腿系统(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能:具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

[C++网络协议] 优于select的epoll

1.epoll函数为什么优于select函数 select函数的缺点: 调用select函数后,要针对所有文件描述符进行循环处理。每次调用select函数,都需要向该函数传递监视对象信息。 对于缺点2,是提高性能的最大障碍。因为,套接字是…

python+requests+pytest+allure自动化框架

1.核心库 requests request请求 openpyxl excel文件操作 loggin 日志 smtplib 发送邮件 configparser unittest.mock mock服务 2.目录结构 base utils testDatas conf testCases testReport logs 其他 2.1base base_path.py 存放绝对路径,dos命令或Jenkins执行…

C++,异常、转换函数、智能指针

目录 一、异常 1 C 异常机制: 2 使用try catch进行异常处理. 3、c 已经内置标准异常类,专业用于抛出的语法中 4 自定义异常: 5 函数只抛出,不处理。让上层函数处理,并且上层函数还可以不处理,让上上层…

Spring 学习(六)代理模式

10. 代理模式 案例 10.1 静态代理 角色分析 抽象角色:一般使用接口或者抽象类实现。真实角色:被代理的角色。代理角色:代理真实角色,含附属操作。客户:访问代理对象的角色。 租房案例 定义租赁接口 /*** TODO* 租房*…

MySQL 基础

本系列文章为【狂神说 Java 】视频的课堂笔记,若有需要可配套视频学习。 1. 简介 数据库(DB,Database)是安装在操作系统上的存储数据的软件。 关系型数据库(RDB)以行列形式存储数据。 非关系型数据库&am…

竞赛选题 基于视觉的身份证识别系统

0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于机器视觉的身份证识别系统 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-sen…

第二届全国高校计算机技能竞赛——Java赛道

第二届全国高校计算机技能竞赛——Java赛道 小赛跳高 签到题 import java.util.*; public class Main{public static void main(String []args) {Scanner sc new Scanner(System.in);double n sc.nextDouble();for(int i 0; i < 4; i) {n n * 0.9;}System.out.printf(&…

JavaScript系列从入门到精通系列第四篇:JavaScript基本语法(二)

文章目录 前言 一&#xff1a;Number类型 1&#xff1a;字符串与Number类型 2&#xff1a;检查数据类型 3&#xff1a;Number最大值 4&#xff1a;Number四则运算精确性 二&#xff1a;布尔值 1&#xff1a;布尔值数量 2&#xff1a;布尔值类型查看 三&#xff1a;N…

基于微信小程序的电影院订票系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明用户微信小程序端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考源码获取 前言 &#x1f497;博主介绍&…

python -文件相关操作

文章目录 前言python -文件相关操作1. 读取文件1.1. 读取整个文件内容1.2. 读取文件的一行内容1.3. 将文件的内容按行存储到一个列表中 2. 写入文件3. 删除文件4. 追加文件5. 遍历文件5.1. 使用 os 模块 遍历文件5.2. # 使用 glob 模块 遍历文件5.3. 使用os.listdir() 函数遍历…

LeetCode 接雨水 双指针

原题链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题面&#xff1a; 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a…

TS编译选项——不允许使用隐式any类型、不明确类型的this、严格检查空值、编译后文件自动设置严格模式

一、不允许使用隐式any类型 在tsconfig.js文件中配置noImplicitAny属性 {"compilerOptions": {// 不允许使用隐式any类型"noImplicitAny": true} } 开启后即可禁止使用隐式的any类型 注意&#xff1a;显式的any类型并不会被禁止 二、不允许使用不明确类…

uniapp——实现base64格式二维码图片生成+保存二维码图片——基础积累

最近在做二维码推广功能&#xff0c;自从2020年下半年到今天&#xff0c;大概有三年没有用过uniapp了&#xff0c;而且我之前用uniapp开发的程序还比较少&#xff0c;因此很多功能都浪费了很多时间去查资料&#xff0c;现在把功能记录一下。 这里写目录标题 效果图1.base64生成…

算法基础之归并排序

一、归并排序的形象理解 原题链接 示例代码 void merge_sort(int q[], int l, int r) {if (l > r) return;int mid l r >> 1;merge_sort(q, l, mid), merge_sort(q, mid 1, r);int k 0, i l, j mid 1;while (i < mid && j < r) //第一处if (q[i]…

通过410s读取电表数据并接入物联网平台

通过410s读取电表数据并接入物联网平台 设备接线准备设备调试代码实现Modbus TCP Client 读取电表数据读取寄存器数据转成32bit Float格式然后使用modbusTCP Client 读取数据 使用mqtt协议接入物联网平台最终代码实现 设备接线准备 设备调试 代码实现 Modbus TCP Client 读取…

LeetCode刷题

一 螺旋矩阵 题目链接&#xff1a;59. 螺旋矩阵 II - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a;…

【论文阅读 08】Adaptive Anomaly Detection within Near-regular Milling Textures

2013年&#xff0c;太老了&#xff0c;先不看 比较老的一篇论文&#xff0c;近规则铣削纹理中的自适应异常检测 1 Abstract 在钢质量控制中的应用&#xff0c;我们提出了图像处理算法&#xff0c;用于无监督地检测隐藏在全局铣削模式内的异常。因此&#xff0c;我们考虑了基于…

如何正确使用MySQL的索引呢?

前言: 📕作者简介:热爱编程的小七,致力于C、Java、Python等多编程语言,热爱编程和长板的运动少年! 📘相关专栏Java基础语法,JavaEE初阶,数据库,数据结构和算法系列等,大家有兴趣的可以看一看。 😇😇😇有兴趣的话关注博主一起学习,一起进步吧! 一、索引使用…