带你手撕链式二叉树—【C语言】

 前言:

普通二叉树的增删查改没有意义?那我们为什么要先学习普通二叉树呢?

给出以下两点理由:

1.为后面学习更加复杂的二叉树打基础。(搜索二叉树、ALV树、红黑树、B树系列—多叉平衡搜索树)

2.有很多二叉树的OJ算法题目都是出在普通二叉树的基础上


让我们开始数据结构链式二叉树之旅吧!!!


1. 链式二叉树的遍历

1.1 前序、中序以及后序遍历概念

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历

1. 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。     访问顺序—— 根 —> 左子树—>右子树

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

            访问顺序—— 左子树—>根 —>右子树

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

             访问顺序—— 左子树—>右子树—>根

 举例




1.2 前序、中序以及后序遍历代码实现

1.2.1创建二叉树节点

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

1.2.2 手动搓出一颗二叉树

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

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

BTNode* BuyNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	assert(node);

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

	return node;
}

BTNode* CreatBinaryTree()  //搓树
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);

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

	return node1;
}

void PreOrder(BTNode* root) //前序遍历
{
	if (root == NULL)
	{
		printf("# ");
		return;
	}

	printf("%d ", root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}

void InOrder(BTNode* root)//中序遍历
{
	if (root == NULL)
	{
		printf("# ");
		return;
	}

	InOrder(root->left);
	printf("%d ", root->data);
	InOrder(root->right);
}

void PostOrder(BTNode* root)//后序遍历
{
	if (root == NULL) {
		printf("# ");
		return;
	}

	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->data);
}


int main()
{
	BTNode* root = CreatBinaryTree();

	PreOrder(root);//前序遍历
	printf("\n");

	InOrder(root);//中序遍历
	printf("\n");

	PostOrder(root);//后序遍历
	printf("\n");

	return 0;
}

1.2.3 代码结果

1.2.4 递归展开图

(学习二叉树的链式结构,一定要学会画递归展开图)

注意:访问到空树的时候,return的时候不是结束递归,是返回到函数被调用的地方

下面是前序遍历的左子树的递归展开图(右子树原理同理) 》》》



2. 求二叉树节点的个数

2.1 全局count的方式(不推荐)

在写代码的过程中要尽量少使用全局变量,这里也是一样的,采用全局变量会有下面的问题:

我们在调用两次的情况下,count会加倍

代码实现

int count = 0;
void TreeSize1(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

	++count;
	TreeSize1(root->left);
	TreeSize1(root->right);
}


2.2 采用分治的思路

将一颗二叉树分解为3个部分——根节点、左子树、右子树

代码实现:

int TreeSize2(BTNode* root)
{
	return root == NULL ? 0 :
		TreeSize2(root->left) + TreeSize2(root->right) + 1;
}

递归展开图

注意:这里的二叉树和上面的不一样(但是计算方式的大致一样的)


蓝色的数字是递归的次序

红色的数字1,表示返回节点的个数——最后是左子树返回3、右子树返回3、+1,一共是7个节点(可以看出,+1都是递归返回的时候加)



3. 求二叉树叶子节点的个数


思路分析

什么是叶子节点呢  ——> 左右孩子都是空的节点      像上面的二叉树节点个数就是3


怎么控制呢 ——> 1. 二叉树是空树的

                             2. 二叉树就一个根节点(也就是左右子树为空)

                             3. 到了第三点,那就直接递归到空,递归到空,就进入第二点,返回1

代码实现 

int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;

	if (root->left== NULL && root->right == NULL)
		return 1;

	return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}


4. 求二叉树第k层的节点数量



思路分析

方法:转换成最小规模的子问题

思路:求第k层的节点,转换成左子树的第k-1层+右子树的第k-1层

每递归一次,k都会-1,当k=1时,就会返回1(也可以看出k不可能减到0)


注意点1:这里的k不能写成k--的形式,递归左子树的时候就k--的话,会改变k,到递归右子树的时候就会出问题

注意点2:重要的事情说三遍!!!  return是返回函数被调用的地方,不是结束整个递归

代码实现

int TreeKLevel(BTNode* root, int k)
{
	assert(k >= 1);
	if (root == NULL)
		return 0;

	if (k == 1)
		return 1;

	return TreeKLevel(root->left, k - 1)
		+ TreeKLevel(root->right, k - 1);
}

递归展开图(部分)



   链式二叉树的知识点比较多,小余在这里分成两部分来写,感兴趣的可以等我的下一期哦!!!

如果觉得文章不错,期待你的一键三连哦,你个鼓励是我创作的动力之源,让我们一起加油,顶峰相见!!!

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

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

相关文章

Linux安装MongoDB数据库并内网穿透在外远程访问

文章目录 前言1.配置Mongodb源2.安装MongoDB数据库3.局域网连接测试4.安装cpolar内网穿透5.配置公网访问地址6.公网远程连接7.固定连接公网地址8.使用固定公网地址连接 转发自CSDN cpolarlisa的文章&#xff1a;Linux服务器安装部署MongoDB数据库 - 无公网IP远程连接「内网穿透…

亚马逊开放个人卖家验证入口?亚马逊卖家验证到底怎么搞?

亚马逊卖家账户的安全对于所有卖家来说都非常重要。如果卖家想要在亚马逊上长期稳定地发展&#xff0c;赚取更多的钱并推出更多热卖产品&#xff0c;就必须确保他们的亚马逊卖家账户安全&#xff0c;特别是一直存在的亚马逊账户验证问题。 近期&#xff0c;根据亚马逊官方披露的…

开发敏捷高效 | 云原生应用开发与运维新范式

5 月 18 日&#xff0c;腾讯云举办了 Techo Day 腾讯技术开放日&#xff0c;以「开箱吧&#xff01;腾讯云」为栏目&#xff0c;对外发布和升级了腾讯自研的一系列云原生产品和工具。其中&#xff0c;腾讯云开发者产品中心总经理刘毅围绕“开发敏捷高效”这一话题&#xff0c;分…

单体项目偶遇并发漏洞!短短一夜时间竟让老板蒸发197.83元

事先声明&#xff1a;以下故事基于真实事件而改编&#xff0c;如有雷同&#xff0c;纯属巧合~ 眼下这位正襟危坐的男子&#xff0c;名为小竹&#xff0c;他正是本次事件的主人公&#xff0c;也即将成为熊猫集团的被告&#xff0c;嗯&#xff1f;这究竟怎么一回事&#xff1f;欲…

手写简单的RPC框架(一)

一、RPC简介 1、什么是RPC RPC&#xff08;Remote Procedure Call&#xff09;远程过程调用协议&#xff0c;一种通过网络从远程计算机上请求服务&#xff0c;而不需要了解底层网络技术的协议。RPC它假定某些协议的存在&#xff0c;例如TPC/UDP等&#xff0c;为通信程序之间携…

PMP考试应该要如何备考?如何短期通过PMP?

我从新考纲考完下来&#xff0c;3A通过了考试&#xff0c;最开始也被折磨过一段时间&#xff0c;但是后面还是找到了方法&#xff0c;也算有点经验&#xff0c;给大家分享一下吧。 程序猿应该是考PMP里面人最多的&#xff0c;毕竟有一个30大坎&#xff0c;大部分人还是考虑转型…

什么是网络编程

目录 一、什么是网络编程&#xff1f; 二、协议 1.用户数据报协议(User Datagram Protocol) 2.TCP协议 TCP三次握手过程 三、实例 1.UDP通信程序 实现步骤 TCP接收数据 四、TCP协议和UDP协议的区别和联系 一、什么是网络编程&#xff1f; 1.在网络通信协议下&#xf…

一图看懂!RK3568与RK3399怎么选?

▎简介 RK3568和RK3399都是Rockchip公司的处理器&#xff0c;具有不同的特点和适用场景。以下是它们的主要区别和应用场景。 ▎RK3568 RK3568是新一代的高性能处理器&#xff0c;采用了22nm工艺&#xff0c;具有更高的性能和更低的功耗。它支持4K视频解码和编码&#xff0c;支持…

电脑如何查找重复文件?轻松揪出它!

电脑如何查找重复文件&#xff1f;小编每天要接触各种文档、图片等资料&#xff0c;很多时候下载了一些图片后&#xff0c;我根本记不住&#xff0c;下次看到不错的图片&#xff0c;我又会下载下来&#xff0c;结果就是和之前下载的图片是一样的内容。下载的重复文件多了&#…

人员定位及轨迹管理技术原理及应用领域

人员定位及轨迹管理的实现涉及多种技术和设备。例如&#xff0c;在GPS定位方面&#xff0c;使用卫星系统可以提供全球范围内的准确定位信息。然而&#xff0c;GPS在室内环境下的信号覆盖可能存在限制&#xff0c;因此在室内定位应用中&#xff0c;常常采用无线传感器网络&#…

第一行代码 第十一章 基于位置的服务

第11章 基于位置的服务 在本章中&#xff0c;我们将要学习一些全新的Android技术&#xff0c;这些技术有别于传统的PC或Web领域的应用技术&#xff0c;是只有在移动设备上才能实现的。 基于位置的服务&#xff08;Location Based Service&#xff09;。由于移动设备相比于电脑…

案例分享 | 纽扣电池石墨片厚度及缺陷检测

石墨片是一种导热散热材料&#xff0c;质轻柔软&#xff0c;能够轻松贴合在各种热源点&#xff0c;在新能源、航天、3C电子等领域应用广泛。 汽车钥匙中的纽扣电池也需要使用石墨片&#xff0c;石墨片会有统一的厚度标准&#xff0c;装配过程中表面不可避免地会出现裂纹、划痕…

Maven学习笔记(上)22版

1. 概述部分 1. 什么是 Maven&#xff1f; 为什么要学习Maven&#xff1f; 管理规模庞大的 jar 包&#xff0c;需要专门工具。脱离 IDE 环境执行构建操作&#xff0c;需要专门工具。 1、构建 Java 项目开发过程中&#xff0c;构建指的是使用『原材料生产产品』的过程。 原…

双目测距联合YOLOv8 项目总结

代码贴&#xff1a;双目测距--5 双目相机 联合 YOLOv8_爱钓鱼的歪猴的博客-CSDN博客 0、图片筛选 可以用matlab,对双目图像做个一个筛选&#xff0c;也就是做双目标定。 熟悉matlab的小伙伴完全可以用matlab做双目标定&#xff0c;我是没咋接触过不知道怎么导出标定结果&#…

如何使用ArcGIS制作气温空间分布图

本文使用ArcMap10.2&#xff0c;以湖北省为例&#xff0c;通过空间插值&#xff0c;制作湖北省1981-2010年20年平均气温空间分布图 树谷资料库资源大全 1 数据准备 可在中国气象数据网下载湖北省1981-2010共20年的各区站累年平均气温数据和各区站经纬度数据。打开为txt格式 在…

字节原来这么容易进,是面试官放水,还是公司实在是太缺人?

本人211非科班&#xff0c;之前在字节和腾讯实习过&#xff0c;这次其实没抱着什么特别大的希望投递&#xff0c;没想到字节可以再给我一次机会&#xff0c;还是挺开心的。 本来以为有个机会就不错啦&#xff01;没想到能成功上岸&#xff0c;在这里要特别感谢帮我内推的同学&…

用友助力中核集团建设财务共享中心新华发电分中心,实现业财融合

企业在进行决策时需要大量的财务信息作为依据&#xff0c;财务共享中心的建设可以帮助企业将财务和业务分离后重新有序融合&#xff0c;使得决策数据更有价值&#xff0c;也帮助企业的管理和决策更加贴合实际。 新华水力发电有限公司&#xff08;简称“新华发电”&#xff09;…

单片机GD32F303RCT6 (Macos环境)开发 (二十八)—— 蓝牙透传模块HC-08 Android App开发

蓝牙透传模块HC-08 Android App开发 1、App整体开发思路 a、首先要申请权限&#xff0c;采用动态申请的方式&#xff0c;用户点击确认后方可操作蓝牙。 b、搜索蓝牙&#xff0c;之前的版本用startLeScan函数搜索蓝牙&#xff0c;虽然高版本中依然可用&#xff0c;但是google已…

众多行业适用的这款Lighthouse Apex Z便携粒子计数器有什么优势

Lighthouse Apex Z粒子计数器围绕易用性和可靠性进行构建。是建立在Lighthouse洁净室行业 40 多年的基于问题的学习基础上的解决方案。 采样设置 ApexZ易于使用的样品设置&#xff0c;可以匹配当前的sop&#xff0c;减少丢失位置或采样错误参数的风险。 用户管理 为了提高效…

霍尔电流传感器的注意事项及其在直流列头柜中的应用

安科瑞虞佳豪 霍尔电流传感器​注意事项 &#xff08;1&#xff09;电流传感器必须根据被测电流的额定有效值适当选用不同的规格的产品。被测电流长时间超额&#xff0c;会损坏末极功放管&#xff08;指磁补偿式&#xff09;&#xff0c;一般情况下&#xff0c;2倍的过载电流…