5.3二叉树——二叉树链式结构实现

news2024/9/21 0:43:38

本篇博客梳理二叉树链式结构
明确:二叉树是递归定义
递归的本质:当前问题+子问题,返回条件是最小规模的子问题

一、二叉树的遍历

1.前序、中序与后序遍历

(1)前序:根->左子树->右子树(每个子树也满足这个遍历顺序,下同)
(2)中序:左子树->根->右子树
(3)后序:左子树->右子树->根
分析前序遍历
前序遍历过程
递归展开图如下,红色箭头表示递推,绿色箭头表示回归
前序遍历递归展开图

// 二叉树前序遍历:根-左子树-右子树
void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	printf("%d ", root->data);
	BinaryTreePrevOrder(root->leftChild);
	BinaryTreePrevOrder(root->rightChild);
}

前序遍历结果:
前序遍历结果
1的左右子树是两个红框,红框内的树仍旧满足前序遍历

// 二叉树中序遍历:左子树-根-右子树
void BinaryTreeInOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	BinaryTreeInOrder(root->leftChild);
	printf("%d ", root->data);
	BinaryTreeInOrder(root->rightChild);
}

中序遍历结果:
中序遍历结果

// 二叉树后序遍历:左子树-右子树-根
void BinaryTreePostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	BinaryTreePostOrder(root->leftChild);
	BinaryTreePostOrder(root->rightChild);
	printf("%d ", root->data);
}

后序遍历结果:
后序遍历结果

2.层序遍历(广度优先遍历【BFS】)

逐层访问二叉树的结点
层序遍历
① 算法思想:用队列辅助,上一层带下一层
② 具体操作:队列结点的data存指向二叉树结点的指针,一个结点出列,该节点孩子马上入列(空结点不入列)
③ 画图分析:
层序遍历画图分析
代码实现如下,队列相关的函数可在4.1中找到

// 层序遍历
//用队列辅助,每个节点当中存指向二叉树对应结点的指针
void BinaryTreeLevelOrder(BTNode* root)
{
	Queue queue;
	QueueInit(&queue);
	//注意:队列中链表节点的data要改成BTNode*的指针
	//根节点先入列
	QueuePush(&queue, root);
	while (!QueueEmpty(&queue))
	{
		//一个结点出列,带着其孩子入列,空结点不入列
		BTNode* front = QueueFront(&queue);
		if (front->leftChild != NULL)//左孩子不为空则入列
		{
			QueuePush(&queue, front->leftChild);
		}
		if (front->rightChild != NULL)//右孩子不为空则入列
		{
			QueuePush(&queue, front->rightChild);
		}
		printf("%d ", QueueFront(&queue)->data);
		QueuePop(&queue);//结点出列

	}
	QueueDestroy(&queue);
}

二、结点个数与高度等

二叉树链式结构

typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* leftChild;
	struct BinaryTreeNode* rightChild;
}BTNode;

1.二叉树结点个数:int BinaryTreeSize(BTNode* root);

节点个数返回值如下:

  • 空:return 0
  • 不为空:return 左子树结点数+右子树结点数+1
// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->leftChild == NULL && root->rightChild == NULL)
		return 1;
	else
		return BinaryTreeSize(root->leftChild) +
		BinaryTreeSize(root->rightChild) + 1;
}

2.二叉树叶子结点个数:int BinaryTreeLeafSize(BTNode* root);

叶子结点个数返回值如下

  • 空:return 0
  • 叶子:return 1
  • 非叶子:return 左子树叶子数+右子树叶子数
//二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->leftChild == NULL && root->rightChild == NULL)
		return 1;
	return BinaryTreeLeafSize(root->leftChild)
		+ BinaryTreeLeafSize(root->rightChild);
}

3.二叉树第k层结点个数int BinaryTreeLevelKSize(BTNode* root, int k);

  • 空:return 0
  • 非空且k==1:return 1
  • 非空且k>1:研究左子树第k-1层+右子树第k-1层
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)
		return 0;
	if (root && k == 1)
		return 1;
	return BinaryTreeLevelKSize(root->leftChild, k - 1) +
		BinaryTreeLevelKSize(root->rightChild, k - 1);
}

4.判断二叉树是否为完全二叉树:int BinaryTreeComplete(BTNode* root);

① 算法思想:层序遍历
② 具体操作:层序遍历,把空也带入队列,第一个空出列之后就开始检查,如果队列中还有非空元素,就不是完全二叉树

//判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root)
{
	if (root == NULL)
		return 0;
	//用层序遍历,把所有数据(包括NULL)也带入队列
	//当第一个空出列之后,开始判断,如果队列中还有非空就不是完全二叉树
	Queue queue;
	QueueInit(&queue);
	QueuePush(&queue, root);//根先入队列
	while (!QueueEmpty(&queue))
	{
		BTNode* front = QueueFront(&queue);
		if (front != NULL)
		{
			QueuePop(&queue);
			QueuePush(&queue, front->leftChild);
			QueuePush(&queue, front->rightChild);
		}
		//遇到第一个NULL在队头就开始检查
		if (front == NULL)
		{
			break;
		}
	}
	//注意:NULL指针在队列当中,队列不是空
	while (!QueueEmpty(&queue))
	{
		BTNode* front = QueueFront(&queue);
		if (front == NULL)
		{
			QueuePop(&queue);
		}
		if (front != NULL)//发现队列当中还有不为NULL的元素,就不是完全二叉树
			return 0;
	}
	return 1;
}

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

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

相关文章

全球知名度最高的华人颜廷利:世界公认十大思想家哲学家

全球知名度最高的华人颜廷利:世界公认十大思想家哲学家 在汉语这一中国优秀传统文化的瑰宝中,“色”与“舍”这两个字的发音分别被解读为“思恶”和“识恶”,揭示了一种深奥的文化现象。这种现象的根源,实则来自于我们的感官——眼…

linux上查找某应用所在的绝对路径

linux上查找某应用所在的绝对路径 1、已知应用名称 找到应用的进程号 例:查找nginx的进程号 ps -ef | grep nginx 或者 ps -aux | grep nginx 2、通过端口号找进程号 lsof -i:80 3、通过进程号找到所在目录,Linux在启动一个进程时,系统会在/proc目…

力扣刷题(3)

整数反转 整数反转-力扣 思路&#xff1a; 利用%和/不断循环取待反转整数的最后一位&#xff0c;注意判断是否超出范围。 int reverse(int x){int y0;while(x){if(y > INT_MAX/10 || y < INT_MIN/10)return 0;int tmpx%10;yy*10tmp;x/10;}return y; }字符串转换整数 …

多线程篇(基本认识 - 锁优化)(持续更新迭代)

目录 一、前言 二、阿里开发手册 三、synchronized 锁优化的背景 四、Synchronized的性能变化 1. Java5之前&#xff1a;用户态和内核态之间的切换 2. java6开始&#xff1a;优化Synchronized 五、锁升级 1. 无锁 2. 偏向锁 2.1. 前言 2.2. 什么是偏向锁 2.3. 偏向…

知识产权案件中的消费者问卷调查证据

在知识产权案件中&#xff0c;消费者问卷调查可以作为一种重要的证据形式。通过调查消费者的认知、态度、行为和观点&#xff0c;消费者问卷调查可以提供以下方面的证据支持&#xff1a; 1、商标或产品混淆&#xff1a;消费者问卷调查可以确定消费者对于涉及知识产权的商标或产…

《python语言程序设计》第8章第9题将二进制数作为字符串转换十六进制print和return的区别

在这里我发现了return和print的区别 def binary_to_hex(binary_value):len_text len(binary_value)for i in range(0, len_text, 4):#能把二进制分成四组进行打印print(binary_value[0 i:4 i])#只能运行将前4个数分成一组return binary_value[0 i:4 i]a binary_to_hex(&q…

HarmonyOS--AGC(认证服务/云函数/云存储/云数据库)

HarmonyOS–AGC(认证服务/云函数/云存储/云数据库) 文章目录 一、注册华为账号开通认证服务二、添加项目&#xff1a;*包名要与项目的包名保持一致三、获取需要的文件四、创建项目&#xff1a;*包名要与项目的包名保持一致五、添加json文件六、加入请求权限七、加入依赖八、修改…

Openai api via azure error: NotFoundError: 404 Resource not found

题意&#xff1a;"OpenAI API通过Azure出错&#xff1a;NotFoundError: 404 找不到资源" 问题背景&#xff1a; thanks to the university account my team and I were able to get openai credits through microsoft azure. The problem is that now, trying to us…

VS2022搭建QT及OpenCV环境

1.背景 由于之前VS2022和QT已经安装好了&#xff0c;所以本次的任务主要是下载OpenCV以及在VS2022上集成QT和OpenCV。关于VS2022和QT的安装大家可以参考别的博客。QT选择的版本是6.2.4&#xff0c;OpenCV版本为3.4.5&#xff0c;Windows版本为Win11。 2.OpenCV下载 OpenCV官…

《黑神话:深度探索与攻略指南》——虎先锋隐藏门在哪里

在《黑神话悟空》这款扣人心弦的游戏中&#xff0c;探索隐藏区域和发现秘密宝箱是许多玩家的乐趣所在。特别是戌狗地窖中那个神秘的宝箱&#xff0c;它不仅藏有泡酒物虎舍利等珍贵道具&#xff0c;更是对玩家探索能力的一次考验。然而&#xff0c;不少玩家在寻找虎先锋隐藏门时…

raksmart机云大宽带服务器托管服务内容

RakSmart是一家提供全球数据中心服务的公司&#xff0c;其业务范围涵盖了服务器托管、专用服务器租赁、云服务等多个领域。其中&#xff0c;机柜大带宽服务器托管服务是其特色之一&#xff0c;特别适合那些需要大量带宽资源的企业级客户。下面我们将详细介绍RakSmart的机柜大带…

windows系统安装配置Apache Maven

Date: 2024.07.17 09:45:10 author: lijianzhan 电脑环境: win10系统 Java开发环境: JDK21 Mvn : apache-maven-3.9.9 maven下载地址: https://maven.apache.org/download.cgi 点击链接进入Apache Maven官网&#xff0c;选择apache-maven-3.9.9-bin.zip进行下载。 下载maven…

ecmascript和javascript的区别详细讲解

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; ECMAScript 和 JavaScript 是密切相关的两个概念&#xff0c;但它们在本质上有所区别。以下是对它们的详细介绍和区别分析。 一、概念定义 1. JavaScript 的定义 JavaScript 是一种基于原型的动态脚本语…

【hot100篇-python刷题记录】【最长连续序列】

R7-哈希篇 思路&#xff1a;sort一下先 然后使用双指针遍历计数&#xff0c;同时从数组头开始。 按照题目的意思&#xff0c;相同元素只能取一个&#xff0c;所以可以用set class Solution:def longestConsecutive(self, nums: List[int]) -> int:if len(nums)<1:retu…

开放式耳机的优缺点?五款绝佳王炸顶级力荐!

在运动过程中&#xff0c;我们往往会选择听音乐来提升运动表现&#xff0c;但是在专注音乐和运动时&#xff0c;又很容易忽略了周围的环境&#xff0c;导致运动意外的发生。所以开放式蓝牙耳机的兴起&#xff0c;深受大家的喜爱&#xff0c;尤其是运动爱好者和音乐爱好者&#…

【C++】OJ习题 篇2

&#x1f680;个人主页&#xff1a;奋斗的小羊 &#x1f680;所属专栏&#xff1a;C 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 &#x1f4a5;1、删除有序数组中的重复项&#x1f4a5;2、数组中出现次数超过一半的数字&#x1f4a5;3、最…

【js逆向专题】2.浏览器调试技巧

小节目标: 熟悉 开发者工具的使用熟悉 代码断点的方式熟悉 网页debugger实现方式 一. 浏览器开发者工具 1. element元素面板 展示浏览器渲染之后的页面 2. network网络面板 浏览器请求的数据都会加载在网络面板 3. console控制台面板 可以在控制台调试你对应的代码 4.…

Call openai-node in the backend or call https in the frontend?

题意&#xff1a;在后端调用 openai-node 还是在前端调用 https&#xff1f; 问题背景&#xff1a; I have a web application by ReactJS and Nodejs. This application calls OpenAI APIs. 我有一个使用 ReactJS 和 Node.js 开发的 Web 应用程序。这个应用程序调用 OpenAI …

分享几个简单的Pandas数据处理函数

文末赠免费精品编程资料~~ 大家好&#xff0c;今天给大家简单分享几个好用的Pandas数据处理函数。 id,category,sub_category,sales,year,var1,var2,age,score,status,quantity 1,A,B,100,2019,50,70,35,85,active,100 2,B,C,120,2020,60,80,28,90,inactive,200 3,A,C,110,20…

RTX5源码全家桶集成emWin6.40, Modbus主从,含FreeRTOS版, 探讨一种移植第3方组件通用方法以及使用注意事项2024-08-30

视频&#xff1a; https://www.bilibili.com/video/BV1tFHuenESf RTX5源码全家桶集成emWin6.40, Modbus主从&#xff0c;含FreeRTOS版, 探讨一种移植第3方组件的通用方法以及多任务使用注意事项 提纲&#xff1a; 参考资料: 1、例程下载 RTX5 All In One(2024-08-30 V2.0).7…