【初阶数据结构】掌握二叉树遍历技巧与信息求解:深入解析四种遍历方法及树的结构与统计分析

在这里插入图片描述

初阶数据结构相关知识点可以通过点击以下链接进行学习一起加油!
时间与空间复杂度的深度剖析深入解析顺序表:探索底层逻辑深入解析单链表:探索底层逻辑深入解析带头双向循环链表:探索底层逻辑深入解析栈:探索底层逻辑
深入解析队列:探索底层逻辑深入解析循环队列:探索底层逻辑树与二叉树:从零开始的奇幻之旅理解堆的特性与应用:深入探索完全二叉树的独特魅力

本篇将介绍掌握二叉树的遍历和信息获取方法,有助于我们更好地理解树的结构与统计分析,为接下来学习AVL树与红黑树等高阶数据结构打下基础。对于最后面关于二叉树的特性,需要理解掌握在遇到相关题目可以直接套用。

请添加图片描述
Alt

🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记
🌈初阶数据结构笔记专栏: 初阶数据结构笔记

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
请添加图片描述

文章目录

  • 一、快速搭建二叉树
  • 二、二叉树组成结构
  • 三、二叉树的遍历
    • 3.1 三种常见遍历(前序/中序/后序遍历)
    • 3.2 层序遍历
  • 四、求二叉树相关信息
    • 4.1 二叉树节点个数
    • 4.2 二叉树叶子节点个数
    • 4.3 求这个棵树的高度
    • 4.4 二叉树第k层节点个数
    • 4.5 二叉树查找值为x的节点
    • 4.5 单值二叉树
    • 4.6 相同的树
    • 4.7 树的销毁(后序)
  • 五、二叉树的性质

一、快速搭建二叉树

为了方便我们更快地学习二叉的基本操作,这里直接手动搭建一颗二叉树。不仅如此,在做二叉树相关题目时,由于部分原因做题平台不支持普通用户使用调试功能,可以快速搭建二叉树在本地编译器上进行调试相关操作

typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType _data;struct BinaryTreeNode* _left;struct BinaryTreeNode* _right;
}BTNode;BTNode* BuyNode(BTDataType x)
{BTNode* tmp = (BTNode*)malloc(sizeof(BTNode));if (tmp == NULL){// 处理内存分配失败的情况// 可以选择报错、退出程序或者其他适当的处理方式exit(EXIT_FAILURE)};  // 举例:退出程序tmp->_data = x;tmp->_left = NULL;tmp->_right = NULL;return tmp;
}BTNode* CreatBinaryTree()
{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 node1;
}

二、二叉树组成结构

二叉树大致分为两种

  • 空树
  • 非空:根节点,的左子树,右子树(左右子树可能为空树)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这里插入图片描述
从概念中可以看出来,根据不同节点可以划分多个子树,对此二叉树定义是递归式的,因此后续基本操作都是按照概念实现的。

三、二叉树的遍历

学习二叉树的结构,最简单的方式就是遍历,遍历是二叉树上最重要的运算之一,也是二叉树上进行其他运算的基础。二叉树遍历按照某种特定的规则,依次对二叉树中的节点进行对应的操作,并且每个节点只操作一次。

在这里插入图片描述

3.1 三种常见遍历(前序/中序/后序遍历)

根据规定,访问顺序左子树是先于右子树,导致了二叉树遍历有三种递归式结构前序/中序/后序的遍历,被访问节点必是某子树的根。根据英文缩写可以通过N、L、R表示根、左子树、右子树,对此NLR、LNR和LRN称为先根遍历、中根遍历和后根遍历。

在这里插入图片描述

根据例子更好的理解其中的含义,不然很难get到其中的真谛。尝试下前序/中序/后序,写出访问顺序(空也会访问,用N代表)

在这里插入图片描述

前序:123NNN45NN6NN
中序:N3N2N1N5N4N6N
后序:NN3N2NN5NN641

过程解析:

达到1号节点为根,访问左子树;达到2号节点为根;访问左子树;达到3号节点为根;访问左子树;达到为空位置返回,访问根(3号),访问右子树;达到空位置,以3号为根子树访问完;以2号为根左子树访问完,访问根(2号);以此类推直到遍历完毕(按照这种方式,剩下两种遍历也是很好掌握的)

在这里插入图片描述

3.2 层序遍历

除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历

在这里插入图片描述

void LevelOrder(BTNode* root)
{// 0. 声明队列queue<TreeNode*> q;// 1. 将根节点加入队列q.push(root);// 2. 遍历队列中每个节点while (!q.empty()) {TreeNode* cur = q.front();q.pop();// 3. 记录当前节点值vec.push(cur->val);// 4. 将左右孩子放入队列q.push(cur->left);q.push(cur->right);}
}

这里使用C++语法直接调用库里面的queue容器,直接主要是分享思路,语法看不懂没有关系。

在这里插入图片描述

使用场景:判断是否为完全二叉树(C++代码)。

// 判断是否为完全二叉树
bool isCompleteTree(TreeNode* root) {if (root == nullptr) {return true;}queue<TreeNode*> q;q.push(root);bool foundNull = false;while (!q.empty()) {TreeNode* currentNode = q.front();q.pop();if (currentNode == nullptr) {foundNull = true;} else {if (foundNull) {return false;}q.push(currentNode->left);q.push(currentNode->right);}}return true;
}

大致思路:完全二叉树特性是从左到右是连续的,该特性保证了最后一个位置为空,那么判断是否为完全二叉树只需要在遇到空节点之后不会再出现非空节点即可。可以使用层序遍历(层序遍历也是适用于普通二叉树)如果队列出空,但是队列不为空说明不是完全二叉树.。

四、求二叉树相关信息

4.1 二叉树节点个数

瑕疵版本:使用静态局部变量进行计数

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

瑕疵版本:使用全局变量进行计数

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

方法分析:无论是使用静态还是全局变量,使得生命周期不会受到函数栈帧销毁的影响,可以解决求节点个数的问题。问题在于静态还是全局变量只能被定义一次,这就意味着第一次计算出来的结果是正确的,那么第二次的结果会延用上一次变量存储的值,不会清空重新计数,程序结束(以上一次值为基准)导致结果错误。

修正版本:画图分析
在这里插入图片描述

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

过程解析:这里使用分治思想,可以将求整课树节点个数分为求左右子树节点个数加上根节点之和,不断划分,去看最几步过程去递推和归并去发现规律。比如:以3为根节点,得到左右子树为空返回结果为0,返回给2节点的结果就是0 + 0 + 1(1为根节点)返回结果为:以2为根节点左子树的节点个数BinaryTreeSize(root->left)等于BinaryTreeSize(root->left-left) + BinaryTreeSize(root->left->right) + 1(如果觉得这样子很难理解,建议画图去研究递归的过程)。

4.2 二叉树叶子节点个数

在这里插入图片描述

int BinaryTreeLeafSize(TreeNode* root)
{if (root == NULL) return 0;if (root->left == NULL && root->right == NULL) return 1;return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

过程解析这里也是使用了分治的思想,求整棵树叶子节点个数之和分为求左右子树叶子节点个数之后。根据题目要求访问三种情况:空节点返回0,不是空节点,属于叶子节点返回1,不是空节点也不是叶子节点,使用分治等于左右子树叶子之后。

4.3 求这个棵树的高度

在这里插入图片描述

过程解析这里也是使用了分治的思想,求整棵树高度分为求左右子树高度之间最大的高度再+1

瑕疵版本

int TreeHeight(TreeNode* root)
{if (root == NULL) return 0;return TreeHeight(root->left) > TreeHeight(root->right) ?TreeHeight(root->left) + 1 : TreeHeight(root->right) + 1;
}

在这里插入图片描述

由于TreeHeight(root->left) > TreeHeight(root->right) 的比较是不会记录结果,需要高的那一份再次递归调用,因此多次递归调用 TreeHeight(root->left)TreeHeight(root->right),造成重复计算。

修正版本:(记录得到目前高度进行比较)

int TreeHeight(TreeNode* root) 
{if (root == NULL) return 0;int leftHeight = TreeHeight(root->left);int rightHeight = TreeHeight(root->right);return max(leftHeight, rightHeight) + 1;
}

4.4 二叉树第k层节点个数

在这里插入图片描述

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

过程解析:跟求整棵树节点个数问题是差不多,主要差异在于对于范围的限制,无非添加一个变量(临时变量)进行递归,每一层的k值是不同的,到达一定条件停止返回如果为空返回0,如果为非空返回1,都建立在k>0的前提下。

4.5 二叉树查找值为x的节点

瑕疵版本:在这里插入图片描述

TreeNode* TreeFind(TreeNode* root, BTDataType x)
{if (root == NULL) return NULL;if (root->data == x) return root;TreeFind(root->left, x);TreeFind(root->right, x);return NULL;
}

过程解析:return 是return 上一层的,不是直接到最外层的。这里导致了没有接受到返回值传出。

修正版本

TreeNode* TreeFind(TreeNode* root, BTDataType x)
{if (root == NULL) return NULL;if (root->data == x) return root;TreeNode* ret1 = TreeFind(root->left, x);if (ret1) return ret1;TreeNode* ret2 =  TreeFind(root->right, x);if (ret2) return ret2;return NULL;
}

4.5 单值二叉树

在这里插入图片描述

bool isUnivalTree(TreeNode* root)
{if(root == NULL) return true;if(root->left && root->left->val != root->val)return false;if(root->right && root->right->val != root->val)return false;return isUnivalTree(root->left) && isUnivalTree(root->right);
}

4.6 相同的树

在这里插入图片描述

bool isSameTree(struct TreeNode* p, struct TreeNode* q) 
{//都为空if(p == NULL && q == NULL) return true;//其中一个为空(前面排除了都为空的情况)if(p == NULL || q == NULL) return false;//都不为空且不相等if(p->val != q->val) return false;return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}

4.7 树的销毁(后序)

在这里插入图片描述

五、二叉树的性质

二叉树的性质

  1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2(i-1)个结点

  2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2h-1

  3. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h= log2(n + 1)(ps: 是log以2为底,n+1为对数)

  4. 对任何一棵二叉树, 如果度为0其叶结点个数为 n0, 度为2的分支结点个数为n2,则有 n0 = n2 + 1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二初阶数据结构笔记,希望对你在学习初阶数据结构中有所帮助!
请添加图片描述

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

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

相关文章

25.dom创建、获取、插入、替换、删除、克隆节点

dom节点 -构成页面的每个组成部分&#xff08;标签 属性 文字 注释&#xff09; 节点(所有的文本内容 包括换行和空格) 元素节点(页面上的每个标签) 属性节点(标签上的属性) 注释节点(所有的注释内容包括注释内的空格换行) 创建节点 创建文本节点&#xff1a; var 变量名docume…

Sui基金会公布第一批RFP资助获得者名单

Sui资助计划已经从RFP申请者中选出了第一批受资助名单&#xff0c;这一举措标志着我们在促进Sui生态创新和增长方面迈出的重要一步。RFP计划旨在解决生态内的特定需求&#xff0c;为与我们战略目标一致的项目提供有针对性的支持。 为非技术者打造兼容Kiosk的启动平台 现存问题…

更新:彩虹云商城系统 自助下单免授权无后门源码(修复完整版)

源码简介&#xff1a; 最新更新彩虹云商城系统&#xff0c;自助下单免授权无后门源码&#xff08;修复完整版&#xff09; 自助下单彩虹云商城系统。这玩意儿不简单&#xff0c;它是高效稳定的电商平台&#xff01;免授权源码版本&#xff0c;灵活方便。源码是用PHP语言写的。…

[CP_AUTOSAR]_分层软件架构_接口之内存模块的交互介绍

目录 1、Memory service modules 特征及差异2、Memory 如何通信交互2.1、Memory通信架构2.2、大块的NV数据管理 3、Memory 软件接口4、内存抽象接口的实现3.1、情况1&#xff1a;只使用了一种NV设备类型3.2、情况2&#xff1a;使用了2种或更多的NV设备 4、结论 在前面 关于接口…

2. KNN分类算法与鸢尾花分类任务

鸢尾花分类任务 1. 鸢尾花分类步骤1.1 分析问题&#xff0c;搞定输入和输出1.2 每个类别各采集50朵花1.3 选择一种算法&#xff0c;完成输入到输出的映射1.4 第四步&#xff1a;部署&#xff0c;集成 2. KNN算法原理2.1 基本概念2.2 核心理念2.3 训练2.4 推理流程 3. 使用 skle…

路由数据获取及封装方法

数据库设计 自联表 定义tree字段 public class LabelValue{public int label { get; set; }public string? value { get; set; }public List<LabelValue> children { get; set; }}获取路由方法 public Response<object> getMenuList() {Response<object>…

spark 事件总线listenerBus

事件总线基本流程 图片来源&#xff1a;https://blog.csdn.net/sinat_26781639/article/details/105012302 LiveListenerBus创建 在sparkContext初始化中创建LiveListenerBus对象。 主要变量有两个 queues&#xff1a;事件队列&#xff0c;里面存放四个队列&#xff0c;每…

零基础学习Python(三)

1. 多重继承 一个子类可以继承多个父类&#xff0c;这与一些编程语言的规则不通。 如果多个父类中有同名的变量和方法&#xff0c;子类访问的顺序是按照继承时小括号里书写的顺序进行访问的。 可以用issubclass(B, A)方法判断B是否为A的子类。 2. 绑定 类中的方法通过参数s…

Unity 导入MRTK,使用URP 升级材质,MRTK的材质还是洋红色

控制台显示信息 ToggleBackground material was not upgraded. There’s no upgrader to convert Mixed Reality Toolkit/Standard shader to selected pipeline UnityEditor.Rendering.Universal.UniversalRenderPipelineMaterialUpgrader:UpgradeProjectMaterials() (at 点击…

Windows 电脑部署 ollama3 并安装模型

Windows 电脑部署 ollama3 并安装模型 部署中为了尽可能减少对本地环境的污染&#xff0c;使用 Docker 安装&#xff01; github: https://github.com/ollama/ollama 准备部署文件 version: 3.8services:ollama:volumes:- ./models:/root/.ollama # 将本地文件夹挂载到容器中…

window11 部署llama.cpp并运行Qwen2-0.5B-Instruct-GGUF

吾名爱妃&#xff0c;性好静亦好动。好编程&#xff0c;常沉浸于代码之世界&#xff0c;思维纵横&#xff0c;力求逻辑之严密&#xff0c;算法之精妙。亦爱篮球&#xff0c;驰骋球场&#xff0c;尽享挥洒汗水之乐。且喜跑步&#xff0c;尤钟马拉松&#xff0c;长途奔袭&#xf…

AWS与其他友商云相比的优势

亚马逊网络服务(AWS)作为全球领先的云计算平台,在激烈的市场竞争中一直保持着领先地位。尽管其他云服务提供商如微软Azure和谷歌云平台也在不断发展,但AWS仍然拥有一些显著的优势。本文将结合九河云的分析探讨AWS相较于其他友商云服务的主要优势。 1. 全面的服务生态系统 AWS…

spring boot(学习笔记第十三课)

spring boot(学习笔记第十三课) 传统后端开发模式和前后端分离模式的不同&#xff0c;Spring Security的logout&#xff0c;invalidateHttpSession不好用&#xff0c;bug&#xff1f; 学习内容&#xff1a; 传统后端开发模式 vs 前后端分离模式Spring Security的logout功能inv…

初学者如何通过建立个人博客盈利

建立个人博客不仅能让你在网上表达自己&#xff0c;还能与他人建立联系。通过博客&#xff0c;可以创建自己的空间&#xff0c;分享想法和故事&#xff0c;并与有相似兴趣和经历的人交流。 本文将向你展示如何通过建立个人博客来实现盈利。你将学习如何选择博客主题、挑选合适…

[C/C++入门][ifelse]19、制作一个简单计算器

简单的方法 我们将假设用户输入两个数字和一个运算符&#xff08;、-、*、/&#xff09;&#xff0c;然后根据所选的运算符执行相应的操作。 #include <iostream> using namespace std;int main() {double num1, num2;char op;cout << "输入 (,-,*,/): &quo…

git镜像链接

镜像链接https://registry.npmmirror.com/binary.html?pathgit-for-windows/ CNPM Binaries Mirror 1.git init 2.克隆 IDEA集成git git分支

springboot助农电商系统-计算机毕业设计源码 08655

基于移动端的助农电商系统的设计与实现 XXX专业XX级XX班&#xff1a;XXX 指导教师&#xff1a;XXX 摘要 近年来&#xff0c;电子商务的快速发展引起了行业和学术界的高度关注。基于移动端的助农电商系统旨在为用户提供一个简单、高效、便捷的农产品购物体验&#xff0c;它不…

SpringCloud教程 | 第九篇: 使用API Gateway

1、参考资料 SpringCloud基础篇-10-服务网关-Gateway_springcloud gateway-CSDN博客 2、先学习路由&#xff0c;参考了5.1 2.1、建了一个cloudGatewayDemo&#xff0c;这是用来配置网关的工程&#xff0c;配置如下&#xff1a; http://localhost:18080/aaa/name 该接口代码如…

关于思维和智能体模型的思考(3)

在前面的讨论中我们已经提出&#xff0c;基于Agent 的AI 应用软件是由一组Agent 和环境信息构成的。其中环境信息非常重要&#xff0c;它们是大模型完成目标的重要依据。他决定了大模型思维的脉络。本文我们讨论环境信息。 环境信息的主要内容 每一次对话而言&#xff0c;大语…

LLaMA-Factory

文章目录 一、关于 LLaMA-Factory项目特色性能指标 二、如何使用1、安装 LLaMA Factory2、数据准备3、快速开始4、LLaMA Board 可视化微调5、构建 DockerCUDA 用户&#xff1a;昇腾 NPU 用户&#xff1a;不使用 Docker Compose 构建CUDA 用户&#xff1a;昇腾 NPU 用户&#xf…