二叉树链式结构的实现——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;elsereturn 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;}
}

 

 


 

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

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

相关文章

免费采集工具推荐,好文章值得收藏

采集工具的作用 在互联网的海洋中,有许多强大的免费采集工具,它们为用户提供了便捷、高效的方式,帮助用户从各种网站中收集、整理所需的信息。这些工具不仅广泛应用于市场研究、竞争情报等商业领域,同时也服务于学术研究、个人兴…

Embedding And Word2vec

Embedding与向量数据库: Embedding 简单地说就是 N 维数字向量,可以代表任何东西,包括文本、音乐、视频等等。要创建一个Embedding有很多方法,可以使用Word2vec,也可以使用OpenAI 的 Ada。创建好的Embedding&#xff…

【开源】基于JAVA的超市账单管理系统

项目编号: S 032 ,文末获取源码。 \color{red}{项目编号:S032,文末获取源码。} 项目编号:S032,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统设计3.1 总体设计3.2 前端设计3…

Beta冲刺总结随笔

这个作业属于哪个课程软件工程A这个作业要求在哪里beta冲刺事后诸葛亮作业目标Beta冲刺总结随笔团队名称橘色肥猫团队置顶集合随笔链接Beta冲刺笔记-置顶-橘色肥猫-CSDN博客 文章目录 一、Beta冲刺完成情况二、改进计划完成情况2.1 需要改进的团队分工2.2 需要改进的工具流程 三…

基于ASP的购物网站设计

摘 要 随着计算机科学的不断发展和网络的迅速普及,Internet 的应用已经涉及到人们生活的方方面面,越来越多的现代企业也意识到了这一点,如何在当前的网络大发展的背景下开拓市场已经成为了企业关注的重中之重。总的来说,互联网的…

从零开始搭建博客网站-----登陆页面

登录按钮以及背景图设置 安装element-plus和css插件 npm install element-plus --save npm install sass --save npm install sass-loader --save在main.js里引用 寻找背景图存入assets文件下,并且在Login.vue里设置背景图和登录按钮 设置的背景图的大小没有起…

智慧安防三大信息技术:云计算、大数据及人工智能在视频监控EasyCVR中的应用

说到三大信息技术大家都很清楚,指的是云计算、大数据和人工智能,在人工智能(AI)快速发展的当下,例如常见的大数据分析、人工智能芯片生产的智能机器人等等,在工作、生活、教育、金融、科技、工业、农业、娱…

Unity 与 虚拟机ROS连接

Unity 与 虚拟机ROS连接 知识储备前期准备ROS部分Unity部分 连接测试 知识储备 unity官方教程: https://github.com/Unity-Technologies/Unity-Robotics-HubWin11家庭版开启HyperV: https://zhuanlan.zhihu.com/p/577980646HyperV安装Ubuntu: https://b…

可视化开源编辑器Swagger Editor本地部署并实现远程访问管理编辑文档

最近,我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念,而且内容风趣幽默。我觉得它对大家可能会有所帮助,所以我在此分享。点击这里跳转到网站。 文章目录 Swagger Editor本地接口文档公网远程访问1. 部署Swagge…

工业机器视觉megauging(向光有光)使用说明书(二,轻量级的visionpro)

测试程序暂时支持80万(包含1024*768)以上的gige工业相机,以后会支持640*480分辨率相机。 我们程序中使用注意力机制,其实就是感兴趣区域(roi,你看过我前面博文,就应该明白)精神的延…

如何让企业报修、派单更高效!自动派单系统有什么用?

最近有做学校后勤报修、物业、酒店民宿的朋友找到我,聊得最多的就是关于任务分发的事情,觉得工作任务派单好难!   我也从跟他们聊天过程中简单整理了以下两种报修派单中普遍存在的问题:   第一种就是有人打电话报修&#xff0…

FreeRTOS入门

目录 一、什么是任务 二、创建任务---xTaskCreate函数 三、任务的删除 四、任务优先级 1.阻塞状态(Blocked) 2.暂停状态(Suspended) 3.就绪状态(Ready) 五、Delay 六、调度算法 一、什么是任务 在FreeRTOS中,任务就是一个函数,原型如下&#xff…

保护您的数据库免受注入攻击:MSSQL注入入门指南

MSSQL注入的入门讲解 一、引言二、MSSQL注入的基础知识2.1、MSSQL数据库的基本原理和结构2.2、常见的SQL语句和操作2.3、MSSQL注入的原理和工作方式 三、MSSQL注入攻击技术3.1、基于错误的注入攻击:利用错误消息和异常信息3.2、基于时间的注入攻击:利用延…

Nacos 架构原理

基本架构及概念​ 服务 (Service)​ 服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态&#xff0c…

Vue3 的 inject 和 provide (附源码)

一:前言 在前端项目中牵扯的最多的莫过于组件之间的传值了,除了最最常用的 props 和 emit,其实在 Vue 中还额外提供了另外几种方法。今天分享一种组件之间通信的方法:provide 和 inject。 二:使用 1、目录结构 以下是…

配置攻击防范示例

1、组网需求。 如果局域网内存在Hacker向SwitchA发起畸形报文攻击、分片报文攻击和泛洪攻击,将会造成SwitchA瘫痪。为了预防这种情况,管理员希望通过在SwitchA上部署各种攻击防范措施来为用户提供安全的网络环境,保障正常的网络服务。 2、配…

【测试开发】第五节.测试——自动化测试(Selenium工具)

作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:Java测试开发 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!! 前言 一、…

匿名结构体类型、结构体的自引用、结构体的内存对齐以及结构体传参

文章目录 🚀前言🚀结构体✈️结构体类型的声明✈️结构体变量的创建与初始化✈️结构体类型的特殊声明✈️结构体的自引用✈️结构体的内存对齐🚁修改默认对齐数 ✈️结构体传参 🚀前言 在C语言中有着各种数据类型,这…

Linux部署HDFS集群

(一)VMware虚拟机中部署 ps、其中node1、node2、node3替换为自己相应节点的IP地址,或者host文件中配置过的主机名,或者看前置准备 或者查看前置准备:Linux部署HDFS集群前置准备 1.下载压缩包 https://www.apache.or…

ChatGPT 问世一周年之际,开源大模型能否迎头赶上?

就在11月30日,ChatGPT 迎来了它的问世一周年,这个来自 OpenAI 的强大AI在过去一年里取得了巨大的发展,迅速吸引各个领域的用户群体。 我们首先回忆一下 OpenAI和ChatGPT这一年的大事记(表格由ChatGPT辅助生成)&#x…