二叉树创建和遍历(及相关OJ题)

个人主页    :敲上瘾-CSDN博客
二叉树介绍:二叉树(详解)-CSDN博客

目录

一、二叉树的创建

二、二叉树的遍历

1.前序遍历

2.中序遍历

3.后序遍历

4.层序遍历

三、相关计算

1.总节点个数计算

2.叶子节点个数计算

3.深度计算


一、二叉树的创建

        关于二叉树的创建和遍历我们考虑用递归来实现。
        我们通过前序遍历的数组"ABD##E#H##CF##G##" 来创建数组,其中 '#' 相当于空指针。

头文件的声明:

typedef char BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType _data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}BTNode;
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)
{
	if (*pi == n)
		return NULL;
	int val = a[(*pi)++];
	if (val == '#')
		return NULL;
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	assert(root);
	root->_data = val;
	root->_left = BinaryTreeCreate(a, n, pi);
	root->_right = BinaryTreeCreate(a, n, pi);
	return root;
}

二、二叉树的遍历

        学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的结点进行相应的操作,并且每个结点只操作一次。访问结点所做的操作依赖于具体的应用问题。

        遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。
按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:
        1. 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
        2. 中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
        3. 后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

1.前序遍历

 

void BinaryTreePrevOrder(BTNode* root)
{
	if (!root)
	{
		printf("#");
		return;
	}
	printf("%c", root->_data);
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);
}
//或者这么写:
void PrevOrder(BTNode* root)
{
	if (root)
	{
    	printf("%c", root->_data);
    	PrevOrder(root->_left);
	    PrevOrder(root->_right);
    }
}

2.中序遍历

void BinaryTreeInOrder(BTNode* root)
{
	if (!root)
	{
		printf("#");
		return;
	}
	BinaryTreeInOrder(root->_left);
	printf("%c", root->_data);
	BinaryTreeInOrder(root->_right);
}

3.后序遍历

void BinaryTreePostOrder(BTNode* root)
{
	if (!root)
	{
		printf("#");
		return;
	}
	BinaryTreePostOrder(root->_left);
	BinaryTreePostOrder(root->_right);
	printf("%c", root->_data);
}

4.层序遍历

        层序遍历是一层一层往下遍历的,并不是单个方向深入,像以上三种遍历都可以叫做深度优先遍历,而层序遍历也可以叫做广度优先遍历,它是不能用递归实现的,要实现它我们可以使用一个队列结构,我们把根节点存入队列然后对队列进行操作,把根节点拿出来(Pop)然后把它的左孩子和右孩子依次取出放入队列,然后再次从队头取到根节点重复操作,一次下去直到队列为空,就能完成层序遍历。如下:

void BinaryTreeLevelOrder(BTNode* root)
{
	if (!root)
		return;
	Queue pt;//需要构造出一个队列结构,这里就不在展示
	QueueInit(&pt);
	QueuePush(&pt, root);
	while (!QueueEmpty(&pt))
	{
		BTNode* pf = QueueFront(&pt);
		if (pf)
			printf("%c", pf->_data);
		else
			printf("#");
		QueuePop(&pt);
		if (pf)
		{
			QueuePush(&pt, pf->_left);
			QueuePush(&pt, pf->_right);
		}
	}
}

三、相关计算

1.总节点个数计算

        在计算节点个数的时候,初学着可能会想用一个全局变量,用以上任意方法遍历并计数。这种方法是可行的但不太可靠。像这些二叉树相关的计算我们大多数都可以考虑把它化为小问题去分析。如果是空树的话就是0,如果不是空树就是1+左树的节点个数+右树的节点个数,像这样左树又可以分为左树和右树去解决,可以不断的把问题化小。如下:

int BinaryTreeSize(BTNode* root)
{
	if (!root)
		return 0;
	else
		return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}

2.叶子节点个数计算

这个计算和上一个方法是相似的,不过我们得特别判断以下是否为叶子节点。如下:

int BinaryTreeLeafSize(BTNode* root)
{
	if (!root)
		return 0;
	if (!root->_left && !root->_right)
		return 1;
	return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}

3.深度计算

        求一颗树的深度可以化为就是左子树的深度和右子树中的最大深度,而左子树又可以在化为更小的左右子树的深度就如此递推下去,直到遇到空树才一次回归(返回),这样就把大问题化为小问题用递归实现。如下:

int BinaryTreeHeight(BTNode* root)
{
	if (!root)
		return 0;
	int v1=BinaryTreeHeight(root->_left);
	int v2 = BinaryTreeHeight(root->_right);
	return v1 > v2 ? v1 + 1 : v2 + 1;
}

要注意一点的是千万不要写成下面的方式: 

这样会使一个函数内就有三个递归展开,效率会变得非常非常低。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

❤机器学习正则化算法的总结。耗时10个小时完成。❤

❤纯 干 货~❤ 目录 纯干货 1、L1 正则化(Lasso 正则化) 2、L2 正则化(岭正则化) 3、弹性网络正则化(Elastic Net 正则化) 4、Dropout 正则化(用于神经网络) 5、贝叶斯Rid…

风力发电机常见故障分析

风力发电机常见故障分析 风力发电机是风电机组中的核心部件,其运行的可靠性和稳定性对整个风电系统的发电效率至关重要。然而,由于复杂的机械结构和长期暴露在严酷环境中,风力发电机在运行过程中可能会出现各种故障。本文将详细介绍风力发电…

【Linux】深入理解文件操作:从C语言接口到系统调用与缓冲区管理

文章目录 前言:1. 铺垫2. 重新使用C文件接口:对比一下重定向2.1. 什么叫当前路径?2.2. 写入文件2.3. 读文件2.4. 程序默认打开的文件流2.5. 输出2.6. 输入 3. 系统调用提供的文件接口3.1. open 打开文件3.2. open函数返回值 4. 缓冲区问题总结…

MongoDB~索引使用与优化

Study by: https://docs.mongoing.com/indexeshttps://www.cnblogs.com/Neeo/articles/14325130.html#%E5%85%B6%E4%BB%96%E7%B4%A2%E5%BC%95 作用 如果你把数据库类比为一本书,那书的具体内容是数据,书的目录就是索引,所以索引…

【随笔】Git 实战篇 -- 开心 commit 之后,发现有一处bug还需要改,只能 reset 撤销然后再次提交 -- git reset --(四十三)

💌 所属专栏:【Git】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! 💖 欢迎大…

RabbitMQ小结

MQ分类 Acitvemq kafka 优点:性能好,吞吐量高百万级,分布式,消息有序 缺点:单机超过64分区,cpu会飙高,消费失败不支持重试 , Rocket 阿里的mq产品 优点:单机吞吐量也…

如何赋予LLM多模态能力(MLLM)

基本概念 多模态大型语言模型(MLLMs)是人工智能领域的一项前沿技术,旨在设计能够理解和生成跨越多种形式数据输入(如文本和图像)内容的模型。 链接文本和视觉模态:MLLMs能够整合文本和视觉数据源的信息。…

众汇:外汇狙击指标如何使用?

对于投资者来说,我们各位交易的目的是什么?WeTrade众汇认为那就是盈利。所以来说有一个指标对各位投资者来说那是相当有帮助的。这是因为对于交易者而言,利用这些指标可以快速识别盈利的买卖时机。当我们选择一个指标之后,深入了解其适用范围…

【机器学习】机器学习与AI大数据的融合:开启智能新时代

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 机器学习与AI大数据的融合 📒1. 引言📕2. 机器学习与大数据🎩机器学习与大数据的特征🎈大数据如…

基于全志T507-H的Linux-RT实时性测试案例分享

本文将为各位工程师演示全志T507-H工业评估板(TLT507-EVM)基于IgH EtherCAT控制伺服电机方法,生动说明Linux-RT Igh EtherCAT的强大之处! Linux-RT系统的优势 内核开源、免费、功能完善。 RT PREEMPT补丁,使Linux内…

树形结构获取所有直属父级节点

递归获取 let arr [{name: "/",meta: {},children: [{name: "home",},{name: "home2",},{name: "common-components",children: [{name: "form-component",}]},{name: "multilevel-menu",children: [{name: &qu…

【数据结构】复杂度的重要性—–决定程序运行的效率

【数据结构】复杂度的重要性—–决定程序运行的效率 前言 在我们写算法的时候,常常会需要考虑一个问题:这个算法好不好?而这个“好”实际上就取决于是算法的复杂度。 算法复杂度(Algorithmic Complexity)是指算法在编…

粒子系统技术在AI绘画中的创新应用

引言: 随着人工智能技术的飞速发展,AI绘画已经成为艺术创作和数字媒体领域的一大热点。粒子系统作为一种模拟复杂物理现象的技术手段,其在AI绘画中的应用为创作过程带来了前所未有的灵活性和创新性。本文将深入探讨粒子系统技术的原理、特点以…

Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:人工智能消防应用

青鸟消防股份有限公司成立于2001年6月,于2019年8月在深圳证券交易所挂牌上市,成为中国消防报警行业首家登陆A股的企业。公司始终聚焦于消防安全与物联网领域,主营业务为“一站式”消防安全系统产品的研发、生产和销售。公司产品已覆盖了火灾报…

【Linux 网络】高级 IO -- 详解

一、IO 的基本概念 I/O(input/output)也就是输入和输出,在冯诺依曼体系结构当中,将数据从输入设备拷贝到内存就叫作输入,将数据从内存拷贝到输出设备就叫作输出。 对文件进行的读写操作本质就是一种 IO,文…

近邻算法详解:原理、Java实现及应用场景

摘要 近邻算法(Nearest Neighbor Algorithm)是一类基于实例的学习方法,广泛应用于分类和回归问题中。最常见的近邻算法是K近邻算法(K-Nearest Neighbors, KNN),其基本思想是通过计算待分类样本与训练样本的…

内网渗透-详解代理逻辑及隧道

写在前面 红蓝对抗过程中打点以后往往需要进行内网渗透和横向移动,因此大家都需要扎实掌握代理和隧道知识,一款优秀的代理工具也可以给内网渗透带来很大的收益。 1.正向代理: 代理客户端,帮助客户端完成所需请求。 举例&#x…

系统架构设计师【第6章】: 数据库设计基础知识 (核心总结)

文章目录 6.1 数据库基本概念6.1.1 数据库技术的发展6.1.2 数据模型6.1.3 数据库管理系统6.1.4 数据库三级模式 6.2 关系数据库6.2.1 关系数据库基本概念6.2.2 关系运算6.2.3 关系数据库设计基本理论 6.3 数据库设计6.3.1 数据库设计的基本步骤6.3.2 数据需求分析6…

梵几 x TapData:如何高效落地实时数据中台,助力家居企业优化数字营销

使用 TapData,化繁为简,摆脱手动搭建、维护数据管道的诸多烦扰,轻量代替 OGG、DSG 等同步工具,「CDC 流处理 数据集成」组合拳,加速数据流转,帮助企业将真正具有业务价值的数据作用到实处,将“…

【FISCO BCOS 3.0】一、新版本搭链介绍

目录 一、区块链种类的变化 二、搭链演示 1.单群组区块链(Air版本) 2.多群组区块链(Pro版本) 3.可扩展区块链(Max版本) FISCO BCOS的发展速度如日中天,对于稳定的2.0版本而言,偶…