二叉树链式结构的实现——C语言

目录

一、提前说明

二、二叉树的遍历 

2.1前序遍历

2.2中序遍历

2.3后序遍历

2.4代码 

三、二叉树结点个数 

3.1整体思路

3.2代码 

四、二叉树叶子结点个数 

4.1整体思路

4.2代码 

五、二叉树的高度(深度)

5.1整体思路

5.2代码

六、二叉树第k层节点个数

6.1整体思路: 

6.2代码 

七、二叉树查找值为x的节点

7.1整体思路 

7.2代码 


一、提前说明

在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。我们在这里先手动构建一棵“死树”,学完基本操作以后我们再来重新构建。

typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}TreeNode;

TreeNode* CreateTreeNode(int x)
{
	TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
	assert(node);

	node->data = x;
	node->left = NULL;
	node->right = NULL;

	return node;
}

TreeNode* CreateTree()
{
	TreeNode* node1 = CreateTreeNode(1);
	TreeNode* node2 = CreateTreeNode(2);
	TreeNode* node3 = CreateTreeNode(3);
	TreeNode* node4 = CreateTreeNode(4);
	TreeNode* node5 = CreateTreeNode(5);
	TreeNode* node6 = CreateTreeNode(6);
	TreeNode* node7 = CreateTreeNode(7);


	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	node5->right = node7;

	return node1;
}

 

二、二叉树的遍历 

遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础

2.1前序遍历

 前序遍历(Preorder Traversal)——访问结点的操作发生在遍历其子树之前。

2.2中序遍历

中序遍历(Inorder Traversal)——访问结点的操作发生在遍历其子树之中(间)。

2.3后序遍历

后序遍历(Postorder Traversal)——访问结点的操作发生在遍历其子树之后。

 

2.4代码 

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

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

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

紧接着我们用我们的“死树”来验证一下我们的代码:

我们看我们的二叉树其实是非常丑的,但是我们通过验证也证明了我们代码的正确性。

而且在验证的时候还有一个小插曲:当我发现实际和输出不对等时,我没有怀疑代码的正确性,而是发现我的二叉树图画错了。

三、二叉树结点个数 

3.1整体思路

求结点个数那么遍历整个二叉树肯定是必要的,这就是为什么说遍历是最重要的操作的原因 

我们可以看出,如果root为NULL时,返回0,否则都是向上返回左右结点之和,那么我们就可以直接相加,还要加上它本身。

3.2代码 

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

四、二叉树叶子结点个数 

叶结点或终端结点:度为0的节点称为叶节点

4.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);
}

五、二叉树的高度(深度)

5.1整体思路

首先要判断根是否存在,如果根存在,继续向下遍历,再次遍历的时候,先判断其左右子树是否存在,若存在,再遍历其左右子树,此时就不用再进行根判断了,根判断的代码只在进入函数时有效执行。 以下是我们的大致思路,但是递归的图着实太难画了,实在不理解可以仔细参照文字或者自己画: 

在画图的过程中我们也发现了,我们每次都要返回左右子树遍历后的较大值,如何做?


这时我们可以借用C语言库中的较大值函数,而且可以进行代码的简化: 

5.2代码

int BinaryTreeHeight(TreeNode* root)
{
	if (root == 0)
	{
		return 0;
	}
	return fmax(BinaryTreeHeight(root->left), BinaryTreeHeight(root->right)) + 1;
}

六、二叉树第k层节点个数

6.1整体思路: 

 

6.2代码 

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

七、二叉树查找值为x的节点

7.1整体思路 

我认为思路的重点是怎么递归左右子树并当返回其中不为空的值。 

我们要如何验证代码的正确性呢?在return 0处打断点:

另外我们的printf要用p%打印出地址,观察监视的值与输出是否相同。

7.2代码 

TreeNode* BinaryTreeFind(TreeNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}
	else
	{
		TreeNode* leftans = BinaryTreeFind(root->left, x);
		TreeNode* rightans = BinaryTreeFind(root->right, x);
		return leftans == NULL ? rightans : leftans;
	}
}

 

 


 

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

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

相关文章

selenium三猛士

selenium包括三个项目,分别是:Selenium WebDriver,Selenium IDE,Selenium Grid。 Selenium WebDriver Selenium WebDriver是客户端API接口,测试人员通过调用这些接口,来访问浏览器驱动,浏览器再访问浏览器…

数学建模 | MATLAB数据建模方法--机器学习方法

近年来,全国赛的题目中,多多少少都有些数据,而且数据量总体来说呈不断增加的趋势, 这是由于在科研界和工业界已积累了比较丰富的数据,伴随大数据概念的兴起及机器学习技术的发展, 这些数据需要转化成更有意…

Linux的基本指令(4)

目录 20.tar指令(重要):打包/解包,不打开它,直接看内容 21.bc指令 22.uname –r指令: 23.重要的几个热键[Tab],[ctrl]-c, [ctrl]-d 20.tar指令(重要):打包/解包&#…

Kubernetes(K8s)Pod控制器详解-06

Pod控制器详解 Pod控制器介绍 Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类: 自主式pod:kubernetes直接创建出来的Pod,这种pod删除后就没有了,也不会重建 控制器创建…

分享85个节日PPT,总有一款适合您

分享85个节日PPT,总有一款适合您 85个节日PPT下载链接:https://pan.baidu.com/s/1FTbSj2Baix-Cj6n42Cz26g?pwd6666 提取码:6666 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气,收集整理更不易。…

语义分割 U-net网络学习笔记 (附代码)

论文地址:https://link.springer.com/chapter/10.1007/978-3-319-24574-4_28 代码地址:https://b23.tv/PCJJmqN 1.是什么? Unet是一种用于图像分割的深度学习网络模型,其结构由编码器和解码器组成,可以对图像进行像素…

深度学习 -- 神经网络

1、神经网络的历史 2、 M-P模型 M-P模型是首个通过模仿神经元而形成的模型。在M-P模型中,多个输入节点对应一个输出节点y。每个输入x,乘以相应的连接权重w,然后相加得到输出y。结果之和如果大于阈值h,则输出1,否则输出0。输入和输出均是0或1。 公式2.1: …

【代码】多种调度模式下的光储电站经济性最优 储能容量配置分析matlab/yalmip

程序名称:多种调度模式下的光储电站经济性最优储能容量配置分析 实现平台:matlab-yalmip-cplex/gurobi 代码简介:代码主要做的是一个光储电站经济最优储能容量配置的问题,对光储电站中储能的容量进行优化,以实现经济…

08-中介者模式-C语言实现

中介者模式: Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently.(用一个中介对…

2243:Knight Moves

文章目录 题目描述思路1. DFS2. BFS3. 动态规划 解题方法1. DFS2. BFS3. 动态规划 题目描述 题目链接 翻译如下: 注:骑士移动是和象棋里的马一样走的是日字型 你的一个朋友正在研究旅行骑士问题 (TKP),你要找到最短的…

结合贝叶斯定理浅谈商业银行员工异常行为排查

1.贝叶斯定理的数学表达 贝叶斯方法依据贝叶斯定理。关于贝叶斯定理解释如下:首先我们设定在事件B条件下,发生事件A的条件概率,即 ,从数学公式上,此条件概率等于事件A与事件B同时发生的概率除以事件B发生的概率。 上述…

VUE语法-(readonly的用法)将数据设置成只读模式

1、功能概述 在Vue中定义一个变量,这个变量的值不允许被修改,核心是通过readonly设置成只读。 如果不会使用ref和reactive响应式数据参考如下博客: https://blog.csdn.net/tangshiyilang/article/details/134701103 2、具体实现 如下案例…

轻量级万物分割SAM模型——MobileSAM安装实测摘要

目录 0、前言1、准备工作安装python环境说明安装说明 运行测试app安装依赖修改代码 2、实际测试效果自带图片测试其它图片测试1其它图片测试2 总结 0、前言 本文将介绍一种轻量级万物分割SAM模型——MobileSAM的安装和实测情况。SAM是meta公司的一种图像分割大模型&#xff0c…

摩根士丹利:人工智能推动增长

摩根士丹利(NYSE:MS)将人工智能战略整合到其财富管理业务中,标志着竞争性金融格局迈出了变革性的一步。该公司的人工智能计划,包括与 OpenAI 合作开发人工智能聊天机器人,促进了其财富部门的显着增长。值得…

VSCode 开发C/C++实用插件分享——codegeex

VSCode 开发C/C实用插件分享——codegeex 一、codegeex 一、codegeex CodeGeeX 智能编程助手是一款编程插件,CodeGeeX支持多种主流IDE,如VS Code、IntelliJ IDEA、PyCharm、Vim等,同时,支持Python、Java、C/C、JavaScript、Go等多…

C++学习之路(十六)C++ 用Qt5实现一个工具箱(为屏幕颜色提取功能增加一个点击复制的功能)- 示例代码拆分讲解

上篇文章,我们用 Qt5 实现了在小工具箱中添加了《颜色代码转换和屏幕颜色提取功能》功能。今天我们把屏幕颜色提取的功能再扩展一下,让它可以点击复制吧。下面我们就来看看如何来规划开发这样的小功能并且添加到我们的工具箱中吧。 老规矩,先…

CKafka 一站式搭建数据流转链路,助力长城车联网平台降低运维成本

关于长城智能新能源 长城汽车是一家全球化智能科技公司,业务包括汽车及零部件设计、研发、生产、销售和服务,旗下拥有魏牌、哈弗、坦克、欧拉及长城皮卡。2022年,长城汽车全年销售1,067,523辆,连续7年销量超100万辆。长城汽车面向…

mysql手动事务

目录 🚀🚀 简要 手动事务使用案例 事务的特性 事务的隔离级别 脏读 不可重复读 幻读 查看事务隔离级别 设置隔离级别 🫡🫡 简要 mysq事务是自动提交的, 例如insert, update语句等 如下: 想要手动设置mysql事务就需…

操作系统导论——第36章 I/O设备

1. 系统架构 之所以使用分层,这是由于成本和效率之间的平衡 2. 标准设备 接口:向系统其他部分展现的硬件接口 内部结构:设备相关特定实现,几个芯片,CPU和通用内存等 3. 标准协议 While (STATUS BYSY); a、轮询设…

第三节:提供者、消费者、Eureka

一、 提供者 消费者(就是个说法、定义,以防别人叭叭时听不懂) 服务提供者:业务中被其他微服务调用的服务。(提供接口给其他服务调用)服务消费者:业务中调用其他微服务的服务。(调用…