嵌入式学习第三十三天!(二叉树)

news2025/2/23 6:58:37

1. 树的概念:

    1. 树:由n个结点组成的有限集,有且只有一个根结点(由根结点可以访问后继结点),其他结点只有一个前驱结点,但可以有多个后继结点(一对多)。当n = 0时,为空树。

    2. 叶子结点(终端结点):只有前驱结点没有后继结点;非叶子结点,即为分支结点。

    3. 度:子结点的个数称之为度。

    4. 树的度:树中各节点度的最大值。(默认为广度

    5. 深度:从根结点到最底层结点的层数。

    6. 森林:n个互不相交的树的集合。

2. 二叉树的概念:

    1. 二叉树:

        任意一个结点的子结点个数不能超过2个(树的度为2),且子节点的位置不可更改(一旦改变位置,就是两个不一样的二叉树)。

    2.  满二叉树:

        在不增加树的层数的前提下,无法再增加一个结点的二叉树。(叶子结点处在同一层,除了叶子结点以外,其余所有的结点的度都为2)

        特性:满二叉树第k层有2^(k-1)个结点,k层满二叉树总共有2^k-1个结点。

        练习:总结点为4847,求叶子结点为多少?

            首先:2^12 - 1 = 4096 - 1 = 4095, 即可以推断出有13层,即4847 - 4095 = 752个

            但第12层有:2^11 = 2048个,非叶子结点有752 / 2 = 376个

            所以叶子结点:2048 - 376 + 752 = 2424个

    3. 完全二叉树:

        只是删除了满二叉树最底层最右边的连续若干个结点,形成了完全二叉树。

        注意:1. 满二叉树是完全二叉树,但完全二叉树不一定是满二叉树。

                   2. 在满二叉树的基础上,如果要增加结点只能从上至下,从左至右的增加结点;如果要减少结点,只能从下至上,从右至左的删除结点。

3. 二叉树的遍历:

    主要研究一对多的树形结构存储到一对一的线性存储单元中:

    1. 前序遍历:先遍历根节点,再遍历左子树,最后遍历右子树(上图ABCEDFG)

    2. 中序遍历:先遍历左子树,再遍历根节点,最后遍历右子树(上图CBEAFDG)

    3. 后序遍历:先遍历左子树,在遍历右子树,最后遍历根节点(上图CEBFGDA)

    4. 层序遍历:从上至下,从左至右,依次遍历(上图ABDCEFG)

        注意:上诉前三种遍历方法为深度优化算法,第四种遍历方法为广度优先算法。

    练习:

        1. 如果只知道一个二叉树的前序遍历为ABC,求二叉树可能的情况:

        2. 如果知道一个二叉树的前序遍历为ABC,后序遍历为CBA,求二叉树可能的情况:

       3. 知道一个二叉树的前序遍历ABCEHDFG,中序遍历CBHEAFDG,求二叉树可能的情况:

        4. 知道一个二叉树的中序遍历CBHEAFDG,后续遍历CHEBFGDA,求二叉树可能的情况:

        从以上练习我们可以知道二叉树的遍历特性:如果只知道一个二叉树的前序遍历不能还原唯一的二叉树,知道前序遍历+后序遍历也不行,必须知道前序遍历+中序遍历,或者后序遍历+中序遍历才能得到唯一确定的一颗二叉树。

4. 二叉树的实现:

    1. 二叉树的定义:

typedef char BTDATA_TYPE;

typedef struct tree_node
{
	BTDATA_TYPE data;
	struct tree_node *pl;
	struct tree_node *pr;
}TREE_NODE;

    2. 二叉树的创建:

int idx = 0;
int cnt = 0;
char tree[] = {"ABC##EH###DF##G##"};

TREE_NODE *Create_BTree(void)
{
	BTDATA_TYPE data = tree[idx++];
	if(data == '#')
	{
		return NULL;
	}

	TREE_NODE *pnode = malloc(sizeof(TREE_NODE));
	if(pnode == NULL)
	{
		perror("fail to malloc");
		return NULL;
	}
	
	pnode->data = data;
	pnode->pl = Create_BTree();
	pnode->pr = Create_BTree();

	return pnode;
}

    3. 二叉树的前序遍历:

void Pre_Order(TREE_NODE *proot)
{
	if(proot == NULL)
	{
		return;
	}
	printf("%c", proot->data);
	Pre_Order(proot->pl);
	Pre_Order(proot->pr);
}

    4. 二叉树的中序遍历:

void Mid_Order(TREE_NODE *proot)
{
	if(proot == NULL)
	{
		return;
	}
	Mid_Order(proot->pl);
	printf("%c", proot->data);
	Mid_Order(proot->pr);
}

    5. 二叉树的后序遍历:

void Pos_Order(TREE_NODE *proot)
{
	if(proot == NULL)
	{
		return;
	}
	Pos_Order(proot->pl);
	Pos_Order(proot->pr);
	printf("%c", proot->data);
}

    6. 二叉树的层序遍历(结合前一篇的队列实现):

void Link_Layer_Order(TREE_NODE *proot)
{
	QUEUE_LIST *pque = Create_Queue_List();
	if(pque == NULL)
	{
		printf("fail to create queue list\n");
		return;
	}
	
	QUEUE_NODE *pnode = Create_Queue_Node(proot);
	if(pnode == NULL)
	{
		printf("fail to create queue node\n");
		return;
	}

	DATA_TYPE outdata;
	Push_Queue_Link(pque, pnode);

	while(!Is_Empty_Queue(pque))
	{
		Pop_Queue_Link(pque, &outdata);
		printf("%c", outdata->data);
		

		if(outdata->pl != NULL)
		{
			pnode = Create_Queue_Node(outdata->pl);
			Push_Queue_Link(pque, pnode);
		}

		if(outdata->pr != NULL)
		{
			pnode = Create_Queue_Node(outdata->pr);
			Push_Queue_Link(pque, pnode);
		}
		
	}

	Destory_Queue(pque);

	return;
}

    7. 获得二叉树的结点个数:

int Get_PTree_Node_Cnt(TREE_NODE *proot)
{
	if(proot == NULL)
	{
		return 0;
	}
	return 1+Get_PTree_Node_Cnt(proot->pl) + Get_PTree_Node_Cnt(proot->pr);
}

    8. 获得二叉树的层数:

int Get_PTree_Layer_Cnt(TREE_NODE *proot)
{
	if(proot == NULL)
	{
		return 0;
	}
	int layl = Get_PTree_Layer_Cnt(proot->pl);
	int layr = Get_PTree_Layer_Cnt(proot->pr);

	return layl > layr ? layl+1 : layr+1;
}

    9. 销毁二叉树:

void Destroy_PTree(TREE_NODE *proot)
{
	if(proot == NULL)
	{
		return;
	}
	Destroy_PTree(proot->pl);
	Destroy_PTree(proot->pr);
	free(proot);
}

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

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

相关文章

ST表(静态RMQ问题)

static Range Max/Min Query ST表 利用的是动态规划的思想 状态&#xff1a; //st[i][j]-->区间长度为1<<j&#xff0c;在区间[i,i1<<j-1]上的最值 状态转移方程&#xff1a; st[i][j]max(st[i][j-1],st[i(1<<j-1)][j-1]);#include <iostream> #inc…

基于51单片机的传送带调速产品计数proteus仿真设计+程序+设计报告+原理图+讲解视频

这里写目录标题 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单&&下载链接资料下载链接&#xff08;可点击&#xff09;&#xff1a; 基于51单片机传送带计数仿真设计( proteus仿真程序设计报告原理图讲解…

processing完整教程

概述&#xff1a;processing在我眼里就是libgdx的高度封装&#xff0c;如果各位会libgdx&#xff0c;学processing应该可以说是无师自通&#xff0c;当然processing是java语言那边的。 processing是什么&#xff1f; 官网是这样解释的&#xff1a;Processing 是一本灵活的软件…

电脑配置不足的情况下,如何高效运行ANSYS?

ANSYS是一款功能强大的工程仿真软件&#xff0c;它对电脑配置有较高的要求。ANSYS对电脑配置要求高&#xff1f;ansys电脑带不动怎么办&#xff1f;ansys卡住了怎么解决&#xff1f;今天这篇文章一起来看看吧。 当电脑配置不足时&#xff0c;运行ANSYS可能会出现以下情况&…

有必要买超声波洗眼镜机吗?力荐四款实力超群超声波清洗机

在日常生活中&#xff0c;眼镜不仅仅是我们视野的延展&#xff0c;像太阳眼镜&#xff0c;也是有着独特的作用。但是&#xff0c;在每天的使用过程中&#xff0c;眼镜片表面难免会有灰尘&#xff0c;污迹&#xff0c;甚至油渍&#xff0c;这些都会对镜片的材质产生一定的损伤&a…

使用Git管理github的代码库-下

1、打开Git GUI 2、克隆代码库 3、到github代码下载页面&#xff0c;复制链接&#xff08;source location&#xff09; 4、目标路径中src在实际目录中是不存在的&#xff0c;会自动新建&#xff0c;否则会报错 5、添加代码&#xff0c;点击staged changed 6、 commit、push

博客互动革命:如何打造活跃读者社区并提升参与度

CSDN 的朋友你们好&#xff0c;我是未来&#xff0c;今天给大家带来专栏【程序员博主教程&#xff08;完全指南&#xff09;】的第 10 篇文章“与读者互动”。本文揭示了提升技术博客参与度的秘诀。从评论互动到社交媒体策略&#xff0c;本文将指导你如何建立强大的读者社区。掌…

一个注解实现SpringBoot接口请求数据和返回数据加密,提高系统安全性!

注解实现接口加密 1、前言1.1、前端必看1.2、后端必看 2、后端注解实现2.1、实现流程2.2、开始实现2.2.1、 pom2.2.2、 注解2.2.3、 加密工具类2.2.3、 定义切面(注意切点包名)2.2.4、 定义加密基类与各种入参VO2.2.5、写两个Controller 3、参考文章 1、前言 起因是公司给人开发…

深圳盐田某前沿研究所:OLED透明屏引领未来科技空间

产品&#xff1a;55寸OLED透明屏 项目时间&#xff1a;2024年04月 项目地点&#xff1a;深圳盐田 在科技日新月异的今天&#xff0c;前沿的研究机构不仅追求科研的突破&#xff0c;也在不断探索和尝试将最新科技融入其工作环境之中。深圳盐田的一家前沿研究所便是这一探索的先…

搜维尔科技:Xsens惯性动捕+Manus手套用于游戏开发制作

用户名称&#xff1a;北京源力星聚网络科技有限公司&#xff08;Bilibili控股子公司&#xff09; 主要产品&#xff1a;Xsens MVN link *2 &#xff0c;Manus手套*2 &#xff0c;MVN Animate Pro软件等 使用培训现场 使用2套Xsens MVN link 2副Manus手套Xsens Animate Pro软件…

成都数字产业园深度链接校企双方,共建产学研合作研发中心

在数字经济的浪潮中&#xff0c;企业与学院之间的深度链接显得尤为关键。作为人才输送的源头&#xff0c;学院承载着为社会培育高素质人才的使命&#xff1b;而作为创新与实践的基地&#xff0c;企业则渴望吸引这些新鲜血液&#xff0c;为自身的持续发展注入新的活力。近日&…

Adobe使用常见问题解答,如何续费?

“Adobe系统状态”页上的颜色表示什么&#xff1f; Gray表示我们调查了潜在的服务中断并确定它没有影响。橙色表示轻微问题。红色表示严重问题。蓝色表示定期维护。绿色表示所有服务均运行正常。 如何查看以前的CSO或CMR&#xff1f; 导航到 https://status.adobe.com.单击所…

超声波清洗机哪个品牌好用?热心推荐四款全能硬核的超声波清洗机

要知道&#xff0c;超声波清洗机的出现&#xff0c;对于那些经常戴眼镜的人来说&#xff0c;无疑是一种让他们解放了双手的清洁工具&#xff0c;由于戴着眼镜久了&#xff0c;就算用水冲洗&#xff0c;也不能够清洁到镜片缝隙里的脏污渍&#xff0c;但是随着时间的推移&#xf…

SAP-CentralFinance - 学习心得3 - 应付账款与物料管理之间的集成

业务示例 工厂 1010 需要轮胎和内胎。负责的采购组织将相应的采购订单交给了某知名供应商。数天之后&#xff0c;先收到了货物&#xff0c;然后收到了发票。 物料管理中的组织单位 物流的中央组织对象为工厂。工厂是公司的运营范围或分支。工厂可以是集中交货仓库、地区销售…

(五)STM32F407 cubemx IIC驱动OLED(3)软件篇

这篇文章主要是个人的学习经验&#xff0c;想分享出来供大家提供思路&#xff0c;如果其中有不足之处请批评指正哈。   废话不多说直接开始主题&#xff0c;本人是基于STM32F407VET6芯片&#xff0c;但是意在你看懂这篇文章后&#xff0c;不管是F1,F4,H7等一系列系统硬件IIC配…

Elastic 基于 RAG 的 AI 助手:利用 LLM 和私有 GitHub 问题分析应用程序问题

作者&#xff1a;来自 Elastic Bahubali Shetti 作为 SRE&#xff0c;分析应用程序比以往更加复杂。 你不仅必须确保应用程序以最佳状态运行以确保良好的客户体验&#xff0c;而且还必须了解某些情况下的内部工作原理以帮助排除故障。 分析基于生产的服务中的问题是一项团队运动…

迷宫中离入口最近的出口

题目链接 迷宫中离入口最近的出口 题目描述 注意点 maze[i][j] 要么是 ‘.’ &#xff0c;要么是 ‘’entrance.length 2entrance 一定是空格子出口的含义是 maze 边界上的空格子entrance格子不算出口 解答思路 广度优先遍历找到走i步时所能到达的所有节点位置&#xff0…

趋势交易如何交易?fpmarkets实例分享

通过之前的文章&#xff0c;各位聪明的投资者想必都已经知道什么是趋势交易了 &#xff01;但是趋势交易如何交易呢&#xff1f;其实很简单&#xff0c;只要理解了趋势交易的信号点以及如何获取的信号就能 很快的掌握如何使用趋势交易进行盈利&#xff0c;下面fpmarkets澳福就和…

实验过程演示【计算机网络实验】

前言 这是陈旧已久的草稿2023-05-20 11:23:54 这个是计算机网络的一个实验&#xff0c;现在也不知道这个是啥来着。 现在2024-5-12 22:33:17&#xff0c;发布到[计算机网络实验]专栏中。 实验过程演示 2023-5-18 20:17:45 1&#xff0e;搭建一个多跳网络拓扑&#xff0c;…

ViewModel 完全指南:实践与背后原理全解

一、引言 在现代Android应用开发中&#xff0c;处理UI数据的有效管理和状态保持是开发者面临的重要挑战之一。Google推出的Jetpack组件库中的ViewModel已成为解决这些问题的关键工具。ViewModel旨在以生命周期意识的方式存储和管理界面相关的数据&#xff0c;从而使数据在配置…