【数据结构】(二叉树)计算结点|叶子结点|高度|第K层结点数

 

目录

概念:

特殊的二叉树

二叉树的性质

二叉树的存储结构

二叉树的创建

二叉树遍历 

前序:

中序:

后序:

 计算结点数

计算叶子结点数

计算树的高度(深度)

计算第K层结点数


 

概念:

一颗二叉树是结点的一个有限集合,该集合:

1.或者为空;

2.由一个根节点加上两棵别称为左子树和右子树的二叉树组成;

注:

1. 二叉树不存在度大于2的结点

2. 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树

 

特殊的二叉树

1. 满二叉树: 一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是 说,如果一个二叉树的层数为K,且结点总数是 ,则它就是满二叉树。

2. 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K 的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对 应时称之为完全二叉树。

注:满二叉树是一种特殊的完全二叉树。

二叉树的性质

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

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

3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为n2 ,则有n0 =n2 +1
4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度h = log2(n+1); (是以2为底数,(n+1)为对数)

二叉树的存储结构

二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。 

1. 顺序存储 :

顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费而现实中使用中只有堆才会使用数组来存储;

二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。 

2. 链式存储 :

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是 链表中每个结点由三个域组成,数据域和左右指针域;

左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。

 

顺序存储在 【数据结构】——堆|Top-k|堆排序-CSDN博客

本节着重介绍链式存储;

二叉树的创建

作者水平有限,目前只能手动创建一颗伪二叉树 

 创建链表结构


typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType data;				//数据域struct BinaryTreeNode* left;	//左子树struct BinaryTreeNode* right;	//右子树
}TreeNode;

手动快速创建一个二叉树 

//创建一个结点
TreeNode*  BuyTreeNode(BTDataType x)
{TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));assert(node);node->data = x;node->left = NULL;node->right = NULL;return node;
}// 构建树
TreeNode* CreateTree()
{TreeNode* node1 = BuyTreeNode(1);TreeNode* node2 = BuyTreeNode(2);TreeNode* node3 = BuyTreeNode(3);TreeNode* node4 = BuyTreeNode(4);TreeNode* node5 = BuyTreeNode(5);TreeNode* node6 = BuyTreeNode(6);TreeNode* node7 = BuyTreeNode(7);node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;//增加一个结点//node5->right = node7;//返回根结点return node1;
}

 

二叉树遍历 

二叉树遍历分为:前序,中序,后序遍历;

前序:访问根结点的操作发生在遍历其左右子树之前

中序:访问根结点的操作发生在遍历其左右子树中间

后序:访问根结点的操作发生在遍历其左右子树之后

注:为了理解透彻,访问到NULL才结束子树的遍历

前序:

 前序遍历是先访问根节点,再访问左子树,左子树根结点访问完后 才会访问左子树结点然后右子树结点;

void PrevOrder(TreeNode* root)
{if (root == NULL){printf("N ");return;}//前序printf("%d ", root->data);PrevOrder(root->left);PrevOrder(root->right);
}

N表示NULL,方便理解 

 

中序:

先行访问左子树,只有左子树访问完后才会访问子树根节点

void PrevOrder(TreeNode* root)
{if (root == NULL){printf("N ");return;}//中序PrevOrder(root->left);printf("%d ", root->data);PrevOrder(root->right);}

 

后序:

void PrevOrder(TreeNode* root)
{if (root == NULL){printf("N ");return;}//后序PrevOrder(root->left);PrevOrder(root->right);printf("%d ", root->data);}

 计算结点数

 递归的核心思想是: 1.子问题分治,

                2.返回条件(递归条件);

1.子问题分治:计算这棵树的结点数,可以理解 左子树结点数+右子树结点数 + 根节点;

左子树结点数又可以分为 左子树结点数+右子树结点数 +子树根节点;

右子树同理;

如何结束递归循环呢?

2.返回条件:遇到结点为NULL, 

 

//计算树的结点数
int TreeSize(TreeNode* root)
{if (root == NULL)return 0;return ((TreeSize(root->left) + TreeSize(root->right)) + 1);
}

计算叶子结点数

叶子结点:没有左右子树的结点;

1.分治:左子树叶子结点数+右子树结点数;

2.返回条件: 如果结点为NULL,返回0;

       如果该结点左右子树为NULL,返回1;

否则往下寻找 直至遇到返回条件;

 

 

//计算叶子结点数
int TreeLeafSize(TreeNode* root)
{//空 返回0if (root == NULL)		return 0;//结点  返回1if (root->left == NULL && root->right == NULL)return 1;//非空 非结点, 说明下面还有结点   左子树+右子树return TreeLeafSize(root->left)+ TreeLeafSize(root->right);
}

计算树的高度(深度)

1.分治:计算左右子树的高度,选择较大数+1 ;

2.递归条件:只有遇到NULL,就表明到该子树尾;

 

 

注:三目比较法会造成极大的负担,因为比较大小后,程序并没有记住较大值是多少,会重复访问; 

//计算树的高度
int TreeHeight(TreeNode* root)
{if (root == NULL)return 0;//return (TreeHeight(root->left) > TreeHeight(root->right) ? TreeHeight(root->left) : TreeHeight(root->right)) + 1;return fmax(TreeHeight(root->left),TreeHeight(root->right)) + 1;
}

计算第K层结点数

计算第K层,相当于计算子树的第K-1层;

注:当K == 1时,要确保该结点存在,所以先行判断结点是否存在,再判断K是否等于1

 

 


//计算第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));
}

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

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

相关文章

PVE系列-防火墙的免费安静之旅IPfire

Ventoy一款引导盘可以引导各种启动盘安装盘的工具https://www.ventoy.net/cn/index.html 在它的兼容iso的列表 中发现了Ipfirehttps://wiki.ipfire.org/ ,本来用着openwrt也挺好,忍不住的虚拟机尝了尝鲜,发现的功能有2, 安全吧&a…

虚拟化之安全虚拟化

虚拟化首次引入是在Armv7-A架构中。那时,Hyp模式(在AArch32中相当于EL2)仅在非安全状态下可用。当Armv8.4-A引入时,添加了对安全状态下EL2的支持作为一个可选特性。 当处理器支持安全EL2时,需要使用SCR_EL3.EEL2位从E…

linux文件打包和压缩

7.2 文件打包和压缩 7.2.1 tar tar(英文全拼:tape archive )命令用于备份文件。 ​ tar 是用来建立,还原备份文件的工具程序,它可以加入,解开备份文件内的文件。 ​ tar命令是Unix/Linux系统中备给文件的…

NetSuite 智能商品推荐(Intelligent Recommendations)

本周在一个客户环境里,发现销售订单中有个Intelligent Recommendations的按钮。 本以为是客户新装的一个SuiteApp,仔细研究一下发现还不是。是个我们忽略的一个内建新功能。 Intelligent Recommendations,是2023.1版本推出的新功能。主要目的…

Qt 表格相关API

1.文本框 限制输入数据类型(如仅英文) QValidator* validator new QRegExpValidator(QRegExp("[a-zA-Z]"), lineText); // 创建正则表达式验证器lineText->setValidator(validator); // 将验证器设置给 QLineEdit QLineEdit:单…

(2023|ICLR,文本反演,LDM,伪词)一个词描述一张图像:使用文本反演个性化文本到图像的生成

An Image is Worth One Word: Personalizing Text-to-Image Generation using Textual Inversion 公纵号:EDPJ(添加 VX:CV_EDPJ 或直接进 Q 交流群:922230617 获取资料) 目录 0. 摘要 1. 简介 2. 相关工作 3. 方…

Vue 2.x跟Vue 3.x有啥区别

大家好,我是咕噜-凯撒,我们都知道Vue 是一款比较流行的前端JavaScript 框架,在他演进的过程中出现了2个主要版本,Vue 2.x 和 Vue 3.x。这两个版本之间有很多的区别,下面我以自己的理解介绍一下他们之间的区别。 响应性…

开源的数据流技术,该选择Redpanda还是Apache Kafka?

本文将比较Apache Kafka和Redpanda两种开源的数据流技术,在云原生实时处理能力上的不同,以及如何在项目中做出选择。 目前,Apache Kafka不但成为了数据流处理领域事实上的标准,而且带动了同类产品的出现。Redpanda就是其中之一…

DeCap DECODING CLIP LATENTS FOR ZERO-SHOT CAPTIONING VIA TEXT-ONLY TRAINING

DeCap: DECODING CLIP LATENTS FOR ZERO-SHOT CAPTIONING VIA TEXT-ONLY TRAINING 论文:https://arxiv.org/abs/2303.03032 代码:https://github.com/dhg-wei/DeCap OpenReview:https://openreview.net/forum?idLt8bMlhiwx2 TL; DR&#xff…

AIGC(生成式AI)试用 15 -- 小结

断断续续的尝试在实际的工作使用中理解和测试AIGC,运用会越来越多、越来越广范,但也是时候做个小结了。 没有太用热火的ChatGPT,只是拿了日常最容易用到的CSDN创作助手(每周写文章总是看到)和文心一言(…

多层记忆增强外观-运动对齐框架用于视频异常检测 论文阅读

MULTI-LEVEL MEMORY-AUGMENTED APPEARANCE-MOTION CORRESPONDENCE FRAMEWORK FOR VIDEO ANOMALY DETECTION 论文阅读 摘要1.介绍2.方法2.1外观和运动对其建模2.2.记忆引导抑制模块2.3. Training Loss2.4. Anomaly Detection 3.实验与结果4.结论 论文标题:MULTI-LEVE…

springboot整合vue,将vue项目整合到springboot项目中

将vue项目打包后&#xff0c;与springboot项目整合。 第一步&#xff0c;使用springboot中的thymeleaf模板引擎 导入依赖 <!-- thymeleaf 模板 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-t…

虚拟机下Ubuntu上网设置

文章目录 一、虚拟机上网的两种方式1.1 NAT模式&#xff08;Network Address Translation&#xff09;1.2 桥接模式&#xff08;Bridge Mode&#xff09;1.3 简介 二、实际配置2.1 NAT模式配置2.2 桥接模式配置 之前跟着博客配了好几个也没用&#xff0c;后来自己慢慢模式实践测…

MySQL数据库 DML

目录 DML概述 添加数据 修改数据 删除数据 DML概述 DML英文全称是Data Manipulation Language(数据操作语言)&#xff0c;用来对数据库中表的数据记录进行增、删、改操作。 添加数据(工NSERT)修改数据(UPDATE)删除数据(DELETE) 添加数据 (1)给指定字段添加数据 INSERT …

【FPGA/verilog -入门学习9】verilog基于查找表的8位格雷码转换

本文参考&#xff1a;FPGA杂记5——格雷码转换设计-CSDN博客 1&#xff0c;什么是查表法&#xff0c;做什么用&#xff0c;有什么好处 查找表&#xff08;Look-Up-Table&#xff09; 查找表&#xff0c;简单说&#xff0c;就是一个预先存储好结果的数据表 通过访问这张预先存储…

【数据分享】2019-2023年我国区县逐年新房房价数据(Excel/Shp格式)

房价是一个区域发展程度的重要体现&#xff0c;一个区域的房价越高通常代表这个区域越发达&#xff0c;对于人口的吸引力越大&#xff01;因此&#xff0c;房价数据是我们在各项城市研究中都非常常用的数据&#xff01;之前我们分享了2019—2023年我国区县逐月的新房房价数据&a…

解决“bat中文路径乱码“问题

今天&#xff0c;在使用.bat脚本&#xff0c;将hello.png从"D:\mypic\备份"目录&#xff0c;拷贝到"D:\mypic\备份"时&#xff1b;发现中文乱码,弹出如下对话框: 图(1) bat中文路径乱码 原来的命令是&#xff1a; copy D:\mypic\one\hello.png D:\mypic\备…

【LangChain学习之旅】—(3) LangChain快速构建本地知识库的智能问答系统

【LangChain学习之旅】—&#xff08;3&#xff09; LangChain快速构建本地知识库的智能问答系统 项目及实现框架开发框架核心实现机制数据准备及加载加载文本文本的分割向量数据库存储文本的“嵌入”概念向量数据库概念 相关信息获取RetrievalQA生成回答并展示示例小结 Refere…

四. 基于环视Camera的BEV感知算法-BEVDet4D

目录 前言0. 简述1. 算法动机&开创性思路2. 主体结构3. 损失函数4. 性能对比总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章——基于环视Cam…

java.lang.IllegalArgumentException: Could not resolve placeholder XXX‘ in value

问题描述 使用Springcloudalibaba的nacos作为配置中心&#xff0c;服务启动时报错&#xff1a; java.lang.IllegalArgumentException: Could not resolve placeholder XXX‘ in value java.lang.IllegalArgumentException: Param ‘serviceName’ is illegal, serviceName is …