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

数据结构——链式二叉树

目录

🍁一、二叉树的遍历

🌕(一)、前序遍历(Preorder Traversal 亦称先序遍历)

🌕(二)、中序遍历(Inorder Traversal)

🌕(三)、后序遍历(Postorder Traversal)

(四)、层序遍历

🍁二、学习链式二叉树的意义

🍁三、二叉树遍历的代码实现

🌕(一)、前序遍历的代码实现

🌕(二)、中序遍历的代码实现

🌕(三)、后序遍历的代码实现

🌕(四)、求节点个数

🌕(五)、求叶子节点的个数

🌕(六)、求第K层的节点个数


🍁一、二叉树的遍历

在此之前我们先了解一下二叉树的四种遍历方式。

二叉树遍历 (Traversal) 是按照某种特定的规则,依次对二叉 树中的节点进行相应的操作,并且每个节点只操作一次

🌕(一)、前序遍历(Preorder Traversal 亦称先序遍历)

即先访问根节点,再访问左子树,最后访问右子树,如下图:

🌕(二)、中序遍历(Inorder Traversal)

即先访问左子树,再访问根节点,最后访问右子树,如下图:

🌕(三)、后序遍历(Postorder Traversal)

即先访问左子树,再访问右子树,最后访问根节点,如下图:

(四)、层序遍历

即一层一层的访问完毕,如下图:

🍁二、学习链式二叉树的意义

(一)、首先我们学习这部分知识要知道的是:普通的二叉树是没有意义的,你说用来存储数据,我直接用顺序表和链表等等不是更方便吗?

(二)、我们在这里学习链式二叉树有两个意义:

①:为后续学习更复杂的二叉树搜索树(如AVL、红黑树)打基础;

②:很多OJ题就喜欢考这一块;

(三)、在这里增删查改不是重点,我们重点学习二叉树的结构(递归结构)

🍁三、二叉树遍历的代码实现

在实现遍历算法之前,为我们首先得有一棵二叉树,因为我们只需要测试某一个功能,所以不需要完整的二叉树结构,这时我们就可以手动的快速建立一个二叉树,如下:

#include<stdio.h>
#include<stdlib.h>//二叉树结构体
typedef struct BinaryTreeNode
{struct BinaryTreeNode* right;struct BinaryTreeNode* left;int val;
}BTNode;//创建一个结点
BTNode* BuyNode(int x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){printf("malloc fail");return;}node->val = x;node->right = NULL;node->left = NULL;return node;
}int main()
{//手动构建一颗二叉树//获得6个结点BTNode* node1 = BuyNode(1);BTNode* node2 = BuyNode(2);BTNode* node3 = BuyNode(3);BTNode* node4 = BuyNode(4);BTNode* node5 = BuyNode(5);BTNode* node6 = BuyNode(6);//手动连接一个二叉树node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;return 0;
}

如上就是该二叉树的代码结构:

🌕(一)、前序遍历的代码实现

//前序遍历
void PrevOrder(BTNode* node1)
{if (node1 == NULL)return;printf("%d ", node1->val);PrevOrder(node1->left);PrevOrder(node1->right);
}

上面就是前序遍历的代码部分,根据规则先访问根节点(即打印),再访问左子树,最后访问右子树(递归),代码部分很简洁,但最重要的是要理解其递归栈帧展开结构

蓝色字体是该位置表示的结点;

红色箭头是代码走向;

红色带圈数字是代码执行顺序;

🌕(二)、中序遍历的代码实现

这三种遍历方法无非就是访问顺序不一样,所以只需要改变相应顺序即可:

//中序遍历
void InOrder(BTNode* node1)
{if (node1 == NULL)return;PrevOrder(node1->left);printf("%d ", node1->val);PrevOrder(node1->right);
}

先访问左子树,再访问根节点(打印),最后访问右子树;

递归栈帧开辟与前序类似,可参考前序遍历自行思考;

🌕(三)、后序遍历的代码实现


//后序遍历
void EndOrder(BTNode* node1)
{if (node1 == NULL)return;PrevOrder(node1->left);PrevOrder(node1->right);printf("%d ", node1->val);
}

🌕(四)、求节点个数

//求结点个数
int TreeSixe(BTNode* root)
{return (root == NULL) ? 0 : (TreeSixe(root->left) + TreeSixe(root->right)+1);
}

求一颗二叉树有多少个节点,我们很容易想到和遍历的思路有关,这样我们就可以写出上述代码:

具体我们可以结合递归栈帧展开图来读代码,由上述所示,我们先计算的是左子树的节点个数,再计算右子树的节点个数,最后再加上当前根节点数,然后返回值,所以这类似于一种后序遍历

🌕(五)、求叶子节点的个数

//求叶子结点个数
int TreeLeafSize(BTNode* root)
{//度为1的节点就可能访问到NULL,所以需要此判断if (root == NULL)return 0;if (root->left == NULL && root->right == NULL)return 1;return TreeLeafSize(root->left) + TreeLeafSize(root->right);}

三种情况:

①:该节点为空,返回0;

②:该节点的左孩子和右孩子都为NULL,即该节点为叶子节点,此时返回1;

③:该节点即不为NULL,也不为叶子节点,即该节点为非叶子节点,此时将任务抛给它的左右子树(左右孩子),所以返回递归和。

注意:

这里有一点容易混淆,就是很多人觉得最多就到叶子节点,不会到空节点,所以第一个if是不是可以不要?答案肯定是要的,因为这种想法是忽略了度为1的非叶子节点的情况,这种节点只有一个孩子,所以当该孩子访问完后就会访问另一个孩子,即访问到NULL;

🌕(六)、求第K层的节点个数

//求第k层的结点数
int TreeKLevel(BTNode* root,int k)
{if (root == NULL){return 0;}if (k == 1)return 1;return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}

如求第三层,即为求第一层的第三层==求第二层的第二层==求第一层的第一层,利用k--1,每递归依次,就进行一次k-1表示到达下一层,当k==1时,即当前层数为要求节点数的层数,若root为NULL,即没有该节点,返回0;若k!=1,root不等于NULL,即还没有到达要求层数,则继续向下层递归。

本次知识到此结束,希望对你有所帮助!

相关文章:

数据结构——链式二叉树

目录 &#x1f341;一、二叉树的遍历 &#x1f315;&#xff08;一&#xff09;、前序遍历(Preorder Traversal 亦称先序遍历) &#x1f315;&#xff08;二&#xff09;、中序遍历(Inorder Traversal) &#x1f315;&#xff08;三&#xff09;、后序遍历(Postorder Traver…...

SpringSecurity笔记

SpringSecurity 本笔记来自三更草堂&#xff1a;https://www.bilibili.com/video/BV1mm4y1X7Hc/?spm_id_from333.337.search-card.all.click&#xff0c;仅供个人学习使用 简介 Spring Security是Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;…...

常见递归算法题目整理

常见递归算法题目整理 一、单路递归1、阶乘计算2、翻转字符串3、二分查找 二、多路递归1、斐波那契1&#xff09;基础版2&#xff09;缓存版 2、汉诺塔3、杨辉三角1&#xff09;基础版2&#xff09;缓存版3&#xff09;优化缓存版 ) 一、单路递归 1、阶乘计算 public class …...

安全小记-Ngnix负载均衡

配置Ngnix环境 1.安装 创建Nginx的目录&#xff1a; mkdir /soft && mkdir /soft/nginx/ cd /home/centos/nginx下载Nginx安装包通过wget命令在线获取安装包&#xff1a; wget https://nginx.org/download/nginx-1.21.6.tar.gz解压Nginx压缩包&#xff1a; tar -x…...

CI/CD

介绍一下CI/CD CI/CD的出现改变了开发人员和测试人员发布软件的方式,从最初的瀑布模型,到最后的敏捷开发(Agile Development),再到今天的DevOps,这是现代开发人员构建出色产品的技术路线 随着DevOps的兴起,出现了持续集成,持续交付和持续部署的新方法,传统的软件开发和交付方…...

window下如何安装ffmpeg(跨平台多媒体处理工具)

ffmpeg是什么? FFmpeg是一个开源的跨平台多媒体处理工具&#xff0c;可以用于录制、转换和流媒体处理音视频。它包含了几个核心库和工具&#xff0c;可以在命令行下执行各种音视频处理操作&#xff0c;如剪辑、分割、合并、媒体格式转换、编解码、流媒体传输等。FFmpeg支持多…...

MySQL必看表设计经验汇总-上(精华版)

目录 1.命名要规范 2选择合适的字段类型 3.主键设计要合理 4.选择合适的字段长度 5.优先考虑逻辑删除&#xff0c;而不是物理删除 6.每个表都需要添加通用字段 7.一张表的字段不宜过多 前言 在数据库设计中&#xff0c;命名规范、合适的字段类型、主键设计、字段长度、…...

扫雷游戏(C语言)

目录 一、前言&#xff1a; 二、游戏规则&#xff1a; 三、游戏前准备 四、游戏实现 1、打印菜单 2、初始化棋盘 3、打印棋盘 4、布置雷 5、排雷 五、完整代码 一、前言&#xff1a; 用C语言完成扫雷游戏对于初学者来说&#xff0c;难度并不是很大&#xff0c;而且通…...

五、MySQL的备份及恢复

5.1 MySQL日志管理 在数据库保存数据时&#xff0c;有时候不可避免会出现数据丢失或者被破坏&#xff0c;这样情况下&#xff0c;我们必须保证数据的安全性和完整性&#xff0c;就需要使用日志来查看或者恢复数据了 数据库中数据丢失或被破坏可能原因&#xff1a; 误删除数据…...

使用dockers-compose搭建开源监控和可视化工具

简介 Prometheus 和 Grafana 是两个常用的开源监控和可视化工具。 Prometheus 是一个用于存储和查询时间序列数据的系统。它提供了用于监控和报警的数据收集、存储、查询和图形化展示能力。Prometheus 使用拉模型&#xff08;pull model&#xff09;&#xff0c;通过 HTTP 协议…...

浏览器——HTTP缓存机制与webpack打包优化

文章目录 概要强缓存定义开启 关闭强缓存协商缓存工作机制通过Last-Modified If-Modified-Since通过ETag If-None-Match 不使用缓存前端利用缓存机制&#xff0c;修改打包方案webpack 打包webpack 打包名称优化webpack 默认的hash 值webapck其他hash 类型配置webpack打包 web…...

STM32duino舵机控制-2

使用定时器进行精确延时&#xff0c;串口接收数据进行 50 0度 --十六进制32 250 180度 --十六进制FA 串口接收到AA 32两个字节&#xff0c;舵机转到0度&#xff1b;接收到AA FA&#xff0c;转到180度。请验证代码&#xff1a; const unsigned…...

【知识---如何创建 GitHub 个人访问令牌】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言登录到 GitHub 帐户。在右上角的头像旁边&#xff0c;点击用户名&#xff0c;然后选择 "Settings"。在左侧导航栏中&#xff0c;选择 "Develope…...

GBASE南大通用分享-ConnectionTimeout 属性

GBASE南大通用分享 获取或设置连接超时时间&#xff0c;值为‚0‛时没有限制。  语法 [Visual Basic] Public Overrides ReadOnly Property ConnectionTimeout As Integer Get [C#] public override int ConnectionTimeout { get; }  实现 IDbConnection.Connecti…...

ChatGPT 全域调教高手:成为人工智能交流专家

随着人工智能的快速发展&#xff0c;ChatGPT作为一种强大的文本生成模型&#xff0c;在各行各业中越来越受到重视和应用。想要利用ChatGPT实现更加智能、自然的交流&#xff0c;成为 ChatGPT 全域调教高手吗&#xff1f;本文将为您介绍如何通过优化ChatGPT的训练方法&#xff0…...

5.Hive表修改Location,一次讲明白

Hive表修改Loction 一、Hive中修改Location语句二、方案1 删表重建1. 创建表&#xff0c;写错误的Location2. 查看Location3. 删表4. 创建表&#xff0c;写正确的Location5. 查看Location 三、方案2 直接修改Location并恢复数据1.建表&#xff0c;指定错误的Location&#xff0…...

基于springboot校园台球厅人员与设备管理系统源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括校园台球厅人员与设备管理系统的网络应用&#xff0c;在外国管理系统已经是很普遍的方式&#xff0c;不过国内的管理网站可能还处于起步阶段。校园台球厅人员与设备管理系统具…...

MySQL(下)

四、事务 一、概念 对数据库的一次执行中有多条sql语句执行。这多条sql在一次执行中&#xff0c;要么都成功执行&#xff0c;要么都不执行。保证了数据完整性。MySQL中只有innodb引擎支持事务。 二、特性 事务是必须满足 4 个条件&#xff08;ACID&#xff09;&#x…...

如何搭建开源笔记Joplin服务并实现远程访问本地数据

文章目录 1. 安装Docker2. 自建Joplin服务器3. 搭建Joplin Sever4. 安装cpolar内网穿透5. 创建远程连接的固定公网地址 Joplin 是一个开源的笔记工具&#xff0c;拥有 Windows/macOS/Linux/iOS/Android/Terminal 版本的客户端。多端同步功能是笔记工具最重要的功能&#xff0c;…...

免费分享一套微信小程序外卖跑腿点餐(订餐)系统(uni-app+SpringBoot后端+Vue管理端技术实现) ,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序外卖跑腿点餐(订餐)系统(uni-appSpringBoot后端Vue管理端技术实现) &#xff0c;分享下哈。 项目视频演示 【免费】微信小程序外卖跑腿点餐(订餐)系统(uni-appSpringBoot后端Vue管理端技术实现)…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...