【数据结构】(二叉树)计算结点|叶子结点|高度|第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…

React 表单与事件

大家好,欢迎来到 React 表单与事件课程。在这一课中,我们将学习如何在 React 中使用表单和事件。 表单 在 HTML 中,表单元素用于收集用户输入。在 React 中,表单元素与其他 DOM 元素有所不同,因为它们会保留一些内部…

linux文件打包和压缩

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

NetSuite 智能商品推荐(Intelligent Recommendations)

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

PHP代码审计之实战审代码篇1

本章代码来之各种php的cms历史漏洞源码,供小伙伴们学习, 本次三题 1. 仔细观察如下代码,思考代码有什么缺陷,可能由此引发什么样的问题? //检测旧密码是否正确 if($password ! ) {$oldpassword md5(md5($oldpassword));$r $do…

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. 方…

react内置组件之<StrictMode></StrictMode>

1、作用&#xff1a; <StrictMode> 是 React 提供的一个组件&#xff0c;用于帮助开发者在开发过程中检测潜在的问题&#xff0c;并修复一些常见的警告。 使用 <StrictMode> 组件包裹应用程序或组件可以启用一些额外的检查和警告。它可以帮助你捕获可能的错误、发…

QSqlQueryModel

QSqlQueryModel 是 Qt 框架中的一个模型类&#xff0c;用于在 Qt 的视图组件&#xff08;如 QTableView、QListView&#xff09;中显示数据库查询结果。 QSqlQueryModel 继承自 QAbstractTableModel&#xff0c;它通过执行 SQL 查询并将结果存储在内部数据结构中&#xff0c;提…

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

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

thinkphp8.0是否兼容thinkphp5.0?

ThinkPHP 8.0 是 ThinkPHP 框架的一个较新版本&#xff0c;而 ThinkPHP 5.0 是其前一个主要版本。每当框架进行主要版本升级时&#xff0c;都会有许多变化&#xff0c;可能包括对现有功能的改进、新功能的添加以及不再支持旧功能。这些变化可能会导致与以前版本的不兼容。 Thi…

流行的 React 相关库和框架

React 本身就是一个非常流行的 JavaScript 库&#xff0c;用于构建用户界面&#xff0c;特别是单页面应用。不过&#xff0c;有许多其他的库和框架与 React 结合使用&#xff0c;以提供额外的功能和优化开发体验。以下是一些最流行的 React 相关库和框架&#xff1a; Next.js&a…

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

本文将比较Apache Kafka和Redpanda两种开源的数据流技术&#xff0c;在云原生实时处理能力上的不同&#xff0c;以及如何在项目中做出选择。 目前&#xff0c;Apache Kafka不但成为了数据流处理领域事实上的标准&#xff0c;而且带动了同类产品的出现。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 论文&#xff1a;https://arxiv.org/abs/2303.03032 代码&#xff1a;https://github.com/dhg-wei/DeCap OpenReview&#xff1a;https://openreview.net/forum?idLt8bMlhiwx2 TL; DR&#xff…

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

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

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

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.结论 论文标题&#xff1a;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 …