二叉树的链式结构

1.二叉树的遍历

2.二叉树链式结构的实现

3.解决单值二叉树题

1.二叉树的遍历

1.1前序,中序以及后序遍历

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

二叉树的遍历有这些规则:前序/中序/后序/的递归结构遍历

1.前序遍历:先访问根结点,再访问左子树,最后访问右子树

2.中序遍历:先访问左子树,再访问根结点,最后访问右子树

3.后序遍历:先访问左子树,再访问右子树,最后根结点 

以前序的规则来遍历二叉树,进入1结点(值为1的结点),1结点为根结点所以先访问,然后是左子树也就是2结点,此时进入2结点后,2结点是根结点,先访问2结点再访问左子树3结点,进入3结点后,以3结点作为根结点,先访问3结点,后访问3结点的左子树,此时就到最后一行都是NULL结点,访问完NULL结点后(3结点的左子树),就访问3结点的右子树(NULL结点),这时候3结点已访问完,而3结点又是2结点的左子树,也就是说2结点的左子树访问完,就访问2结点的右子树(NULL结点),2结点也访问完了,2结点又是1结点的左子树,既1结点的左子树访问完,开始访问1结点的右子树,后续过程也是一样的,每进入一个结点都是新的根结点,按照前序的遍历,总的看就是一个递归过程了,只有3结点的左右子树以及自身被访问完后才去访问上面结点的右子树。

 

 

 

 访问的顺序不同也会带来不同的特点,前序访问则第一个是最上面的结点,中序访问最上面的结点会把其的左右子数分成俩边,后序则最上面的结点在最后面,中序和后序的过程与前序差不多,就是根结点的访问有所不同。

 2.二叉树链式结构的实现

2.1代码实现遍历二叉树数

下面是以前序为规则遍历的代码实现:

#include<stdio.h>
#include<stdlib.h>
typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType data;BinaryTreeNode* left;BinaryTreeNode* right;
}BTNode;
BTNode* BuyNode(int x)
{BTNode* a = (BTNode*)malloc(sizeof(BTNode));if (a == NULL){perror("malloc fail:");return NULL;}a->data = x;a->left = NULL;a->right = NULL;return a;
}
BTNode* CreatNode()
{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;
}
void PrevOver(BTNode* root)
{if (root == NULL){printf("N ");return;}printf("%d ", root->data);PrevOver(root->left);PrevOver(root->right);
}
int main()
{BTNode* root = CreatNode();PrevOver(root);return 0;
}

结果如上面分析的一样。

只需要改变 PrevOver函数中代码的顺序就可以切换成其他的规则的遍历,把左子树放在根的访问前就是中序的遍历规则。

2.2实现计算二叉树中的结点的个数

错误代码1:

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

首先size是在栈区上开辟的空间,当出了这个函数,栈区就会被销毁,函数只会传size的值,size变量是被销毁了,但是没有接受返回的值,等于是去银行取钱,结果忘记拿钱了,这样是找不到累计的效果的,需要理解的是不是名字一样就是同一个变量,在递归的过程中,虽然都是size但是这些size是在不同栈区上开辟的不同变量,只是名字相同,所以最后返回的size是第一次调用的函数的size,最后会返回1.

错误代码2:

通过static可以是局部变量在出函数时不会被销毁掉,保留size的值,使得size能达到计数的效果,

但是也有缺陷,就是在主函数中多次调用计算结点数量的函数会出问题

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

多次调用计算函数:

会导致一直积累

 

错误代码3:

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

只需要把size从局部变量变成全局变量就行,这样递归过程中的每个函数的size都是同一个size了,全局变量的生命周期是程序结束,同static一样,但是相对static的方法安全一些,使用static需要谨慎。

合理代码:

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

把根结点分成左子树和右子树在加1(计入一个结点数量),每次进入一个结点都会有左子树和右子树,每进入一个结点就计入1,直到root=NULL时返回0,就把关于根和子树所计入的数返回到上一个结点去,通过这样会一直返回到最上面的结点,就把所有结点的数量都计入进去了,不会出现多次调用函数而发生数量的变化。

2.3计算二叉树的高度

因为根结点有左右俩个子树,树的高度是由最长的决定的,所有要对比左右俩个子树的长度,找到长度长的子树,再加上一(根结点算一个高度),这样就计算出树的高度了。

错误代码:


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

这样虽然可以计算出树的高度,但是存在一个问题,函数会在树的最下面开始计入,比我后在返回值那里又要计算一次,因为这个是没有变量来存储计入的值,所有每次对比和返回值时都要在通过递归来得到计入的值,如果树的高度是大的,那么当递归到较为上面时,在往下递归就会导致程序运行慢,一直重复计算,计算最底下的结点的度会因为结点的上走而暴增,倒数第二层计算最后一层结点的度会执行俩次,倒数第三层则会计算最后一层结点四次,所以这个代码是不合适的。

改进代码:

分析:

通过递归会找到最下面的结点,既叶子结点,开始往上走,返回的地方就是比较那边大,就往那边加一(这里的一是根的计入),直到走到最上面结点,这时比较就是总的左子树和右子树的高度(不是最上面结点)。

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

创建临时变量来存储函数返的值,就不用重复计算,可以提高运行速度,减少消耗。

2.4计算树的叶子结点个数

叶子结点的左右子数都是NULL,可以以此为特点找。

错误代码:

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

因为二叉树不是所有结点都有左右子树,有些子树是NULL,如果为NULL则是不能用->符号引用的,所以代码是不合理的。

改进代码:

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

先在最前面判断是否为空,在进行下面的操作,就可以避免遇到NULL而去解引。

3.解决单值二叉树题

 题意可以知道单值二叉树是结点的值是一样的,需要去遍历二叉树去判断是否所有的值都相等,

通过判断根和左右子树是否相等,如果每个根和左右子树都相等,则整体的全部值也会相等,就像a=b,b=c,所以a=b=c。

代码:

bool isUnivalTree(struct 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);}

分析:

之所用如果不相等就返回false是因为后面的子结点是否相等还不知道,判断相等就返回true太早了,可能后面的值与前面的不相等,只有全部相等才能返回true。 

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

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

相关文章

主流电商平台商品实时数据采集API接口||抖音电商数据分析实例|可视化

— 1 — 抖音电商数据【抖音电商API数据采集】分析场景 1. 这里&#xff0c;我们选择“伊利”这个品牌作为案例进行分析&#xff0c;在短短的4个月里&#xff0c;从最初每月营收17.07万&#xff0c;到6月份达到了2485.54 万&#xff0c;伊利的牛奶&#xff0c;有点牛&#xff…

Spring 对 Junit4,Junit5 的支持上的运用

1. Spring 对 Junit4,Junit5 的支持上的运用 文章目录 1. Spring 对 Junit4,Junit5 的支持上的运用每博一文案2. Spring对Junit4 的支持3. Spring对Junit5的支持4. 总结&#xff1a;5. 最后&#xff1a; 每博一文案 关于理想主义&#xff0c;在知乎上看到一句话&#xff1a;“…

Xline社区会议Call Up|在 CURP 算法中实现联合共识的安全性

为了更全面地向大家介绍Xline的进展&#xff0c;同时促进Xline社区的发展&#xff0c;我们将于2024年5月31日北京时间11:00 p.m.召开Xline社区会议。 欢迎您届时登陆zoom观看直播&#xff0c;或点击“阅读原文”链接加入会议&#xff1a; 会议号: 832 1086 6737 密码: 41125…

通过cmd命令行使用用3dmax自带的vray渲染

有时调试需要使用vray渲染vrscene文件看效果&#xff0c;只装有3dmax下可以使用自带vray渲染&#xff0c;在3dmax的渲染日志里面看自带引擎路径 使用命令行进入到此目录 执行命令指定vr文件即可看到效果&#xff0c;如&#xff1a;vray.exe -sceneFile“C:\test15\202405241…

Cesium与Three相机同步(2)

之前实现了将Three相机同步到Cesium相机Cesium与Three相机同步(1)-CSDN博客 现在是将Cesium相机同步到Three相机,从而实现了相机双向同步。 <!DOCTYPE html> <html lang="en"><head><title>three.js webgl - orbit controls</title&g…

【教学类-58-03】黑白三角拼图03(4*4宫格)总数算不出+随机抽取10张

背景需求&#xff1a; 【教学类-58-01】黑白三角拼图01&#xff08;2*2宫格&#xff09;256种-CSDN博客文章浏览阅读318次&#xff0c;点赞10次&#xff0c;收藏12次。【教学类-58-01】黑白三角拼图01&#xff08;2*2宫格&#xff09;256种https://blog.csdn.net/reasonsummer/…

【Jmeter】使用Jmeter进行接口测试、跨线程组获取参数

Jmeter接口测试 Jmeter设置成中文实操练习-跨线程组提取参数&#xff0c;使用值HTTP请求默认值&HTTP信息头管理器 相信打算从事测试工程师的同学们&#xff0c;肯定对Jmeter是耳熟能详的。使用Jmeter可以进行接口测试、性能测试、压力测试等等&#xff1b;这个章节介绍如何…

cocos 通过 electron 打包成 exe 文件,实现通信问题

cocos 通过 electron 打包成 exe 文件&#xff0c;实现通信问题 首先&#xff0c;我使用的 cocos 版本是 2.4.12&#xff0c;遇到一个问题&#xff0c;是啥子呢&#xff0c;就是我要把用 cocos 开发出来的项目打包成一个 exe 可执行程序&#xff0c;使用的是 electron &#xf…

【C++算法】BFS解决多源最短路问题相关经典算法题

1.01矩阵 既然本章是BFS解决多源最短路问题&#xff0c;也就是说有若干个起点&#xff0c;那我们就可以暴力一点&#xff0c;直接把多源最短路径问题转化成若干个单源最短路径问题&#xff0c;然后将每次的步数比较一下&#xff0c;取到最短的就是最短路径的结果&#xff0c;这…

arcgis 10.6 工具栏操作error 001143 后台服务器抛出异常

arcgis 10.6 工具栏操作error 001143 后台服务器抛出异常 环境 win10arcgis 10.6 问题 执行定义投影要素转线出现 Error: 001143:后台服务器抛出异常&#xff08;差点重装10.6&#xff09; 如下图所示&#xff1a; 解决方法 通过在菜单工具条上单击地理处理 > 地理处…

设计模式使用(成本扣除)

前言 名词解释 基础名词 订单金额&#xff1a;用户下单时支付的金额&#xff0c;这个最好理解 产品分成&#xff1a;也就是跟其他人合做以后我方能分到的金额&#xff0c;举个例子&#xff0c;比如用户订单金额是 100 块&#xff0c;我方的分成是 80%&#xff0c;那么也就是…

OceanMind海睿思通过上海数交所数商认证,提供高质量数据治理和数据咨询服务

近日&#xff0c;中新赛克海睿思成功通过上海数据交易所的数商认证&#xff0c;获得上海数据交易所颁发的“数据产品开发服务商”、“数据治理服务商”和“数据咨询服务商”三大证书。 作为由深圳市创新投资集团有限公司投资控股的高新技术企业&#xff0c;国家级专精特新“小巨…

如何通过OpenHarmony的音频模块实现录音变速功能?

简介 OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;是由开放原子开源基金会孵化及运营的开源项目&#xff0c;是面向全场景、全连接、全智能时代的智能物联网操作系统。 多媒体子系统是OpenHarmony系统中的核心子系统&#xff0c;为系统提供了相机、…

Java入门基础学习笔记43——包

什么是包&#xff1f; 包是用来分门别类的管理各种不同程序的&#xff0c;类似文件夹&#xff0c;建包有利于程序的管理和维护。 建包的语法规则&#xff1a; package cn.ensource.javabean;public class Car() {} 在自己的程序中调用其他包下的程序的注意事项&#xff1a; 1…

动手学深度学习——层和块

1. 层 层是一个将输入数据转换为输出数据的神经网络组件。每个层都会对输入数据进行一定的操作&#xff0c;例如线性变换、非线性激活函数等&#xff0c;以产生输出数据。 torch.nn模块提供了各种预定义的层&#xff0c;如线性层、卷积层、池化层等&#xff0c; nn.Linear&a…

BLE学习笔记(0.0) —— 基础概念(0)

前言 &#xff08;1&#xff09;本章节主要是对BLE技术进行简单的介绍&#xff0c;熟悉蓝牙技术的发展过程&#xff0c;了解相关术语方便后续的学习。 &#xff08;2&#xff09;为了防止单篇博客太长以至于看不下去&#xff0c;因此我基础概念章节分为两篇来写。 &#xff08;…

Mysql教程(0):学习框架

1、Mysql简介 MySQL 是一个开放源代码的、免费的关系型数据库管理系统。在 Web 开发领域&#xff0c;MySQL 是最流行、使用最广泛的关系数据库。MySql 分为社区版和商业版&#xff0c;社区版完全免费&#xff0c;并且几乎能满足全部的使用场景。由于 MySQL 是开源的&#xff0…

1075: 求最小生成树(Prim算法)

解法&#xff1a; 总结起来&#xff0c;Prim算法的核心思想是从一个顶点开始&#xff0c;一步一步地选择与当前最小生成树相邻的且权值最小的边&#xff0c;直到覆盖所有的顶点&#xff0c;形成一个最小生成树。 #include<iostream> #include<vector> using names…

springboot基于Web前端技术的java养老院管理系统_utbl7

3.普通用户模块包括&#xff1a;普通会员的注册、养老院客房查询、养老院留言查询、预约老人基本信息登记、选择房间、用户缴费的功能。 4.数据信息能够及时进行动态更新&#xff0c;增删&#xff0c;用户搜素方便&#xff0c;使用户可以直接浏览相关信息&#xff0c;要考虑便于…

Vue3实战笔记(35)—集成炫酷的粒子特效

文章目录 前言一、vue3使用tsparticles二、使用步骤总结 前言 学习一个有趣炫酷的玩意开心一下。 tsparticles&#xff0c;可以方便的实现各种粒子特效。支持的语言框架也是相当的丰富. 官网&#xff1a;https://particles.js.org/ 一、vue3使用tsparticles 先来个vue3使用…