[C/C++]数据结构: 链式二叉树的构建及遍历

news2024/9/24 17:17:41

一: 💬二叉树的概念

1.1:🚩 概念

       二叉树是指树中节点的度不大于2的有序树,它是一种最简单且重要的树,二叉树的递归定义为:二叉树是一颗空树,或者是一颗由一个根节点和两颗互不相交的,分别称为跟的左孩子和右孩子树组成的非空树,其中左子树和右子树都是二叉树.

1.2 : ⚡特殊的二叉树

  1. 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是 ,则它就是满二叉树。
  2.  完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

1.3: 🌟二叉树的性质

  1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有 2^(i-1)个结点.
  2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2^h-1 .
  3. 对任何一棵二叉树, 如果度为0其叶结点个数为 , 度为2的分支结点个数为 ,则有 n0=n2 +1
  4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h=lg(n+1) (ps:是log以2为底,n+1为对数)
  5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:

1. 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
2. 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
3. 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子

二:🥦链式二叉树的结构

        二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。由于二叉树可以分为根,左子树,右子树,而其左右子树又可以分为根左子树,右子树,所以链式二叉树非常适合使用递归. 

typedef char BTDataType;

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

三: ⛲链式二叉树的创建及遍历

1.前序遍历:先遍历树的根在遍历书的左子树和右子树

前序遍历递归图解:

代码:

void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}

	printf("%c ", root->data);//先访问根节点
	BinaryTreePrevOrder(root->left);//访问左子树
	BinaryTreePrevOrder(root->right);//访问右子树
}

2.中序遍历:和前序遍历思想一样,不过遍历顺序发生改变,先便利左子树,再遍历根,再遍历右子树

void BinaryTreeInOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}

	BinaryTreeInOrder(root->left);
	printf("%c ", root->data);
	BinaryTreeInOrder(root->right);
}

3.后序遍历:先遍历左子树再遍历右子树最后遍历根节点

void BinaryTreePostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	BinaryTreePostOrder(root->left);
	BinaryTreePostOrder(root->right);
	printf("%c ", root->data);
}

4.层序遍历:

        层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历.

实现方法: 层序遍历要使用到队列,忘记的帖子可以看[C/C++]数据结构 栈和队列

首先将节点1入队列

若1的左右节点不为空,再将左右节点依次入队,再把节点1出队(相当于遍历节点1)

重复上诉步骤,每次出队时先将这个节点不为空的子节点入队,当队列为空时就说明二叉树遍历完了

void BinaryTreeLevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%c ", front->data);

		if (front->left)
			QueuePush(&q, front->left);
		if (front->right)
			QueuePush(&q, front->right);
	}
	QueueDestory(&q);
}

5.二叉树的构建

通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树,其中'#'代表NULL

还是采用递归的思想,首先函数的形参需要一个字符串数组,和一个整形指针,该指针是用来记录访问到数组的位置.遇到'#'就让改指针++,并返回NULL,否则就开辟一个节点,使该节点的数据域指向对应数组的元素,再递归遍历该节点的左子树和右子树

BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
	if (a[*(pi)]=='#')
	{
		(*pi)++;
		return NULL;
	}

	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if (root == NULL)
	{
		perror("malloc");
		exit(-1);
	}

	root->data = a[(*pi)++];
	root->left  = BinaryTreeCreate(a, pi);
	root->right = BinaryTreeCreate(a, pi);
	return root;
}

四:其他相关功能

像求二叉树的节点个数,高度等功能都是利用递归思想解决的,博主就不过多介绍了,需要的帖子可以看下方代码

//节点个数
int BinaryTreeSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	else
		return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	else if (root->left == NULL && root->right == NULL)
		return 1;
	else
		return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	assert(k >0);
	if(root==NULL)
		return 0;
	else if (k == 1)
		return 1;
	else
	{
		return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
	}

}
//求二叉树的高度
int BinaryTreeHeight(BTNode* root)
{
	if (root == NULL)
		return 0;
	else
	{
		int left = BinaryTreeHeight(root->left);
		int right = BinaryTreeHeight(root->right);
		return left > right ? left+1 : right+1;
	}
}
//在二叉树中查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;

	if (root->data == x)
		return root;

	BTNode* ret1 = BinaryTreeFind(root->left, x);
	if (ret1 != NULL)
		return ret1;

	BTNode* ret2 = BinaryTreeFind(root->right, x);
	if (ret2 != NULL)
		return ret2;

	return NULL;
}
//销毁二叉树
void BinaryTreeDestory(BTNode* root)
{
	if (root == NULL)
		return;
	BinaryTreeDestory(root->left);
	BinaryTreeDestory(root->right);
	free(root);
}

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

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

相关文章

设计模式详解:代理模式

1. 什么是代理模式&#xff1f; 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许通过代理对象控制对另一个对象的访问。代理模式在客户端和目标对象之间引入了一个代理对象&#xff0c;客户端通过代理对象间接地访问目标对象&#xff0c…

ComfyUI完整安装教程(Windows版)

话不多说&#xff0c;地址供上&#xff1a; GitHub - comfyanonymous/ComfyUI: The most powerful and modular stable diffusion GUI with a graph/nodes interface.The most powerful and modular stable diffusion GUI with a graph/nodes interface. - GitHub - comfyanon…

如何使用内网穿透工具实现Java远程连接本地Elasticsearch搜索分析引擎

文章目录 前言1. Windows 安装 Cpolar2. 创建Elasticsearch公网连接地址3. 远程连接Elasticsearch4. 设置固定二级子域名 前言 简单几步,结合Cpolar 内网穿透工具实现Java 远程连接操作本地分布式搜索和数据分析引擎Elasticsearch。 Cpolar内网穿透提供了更高的安全性和隐私保…

如何修复无法读取的U盘,修复U盘的方法

无法读取U盘是常见的故障&#xff0c;可能的原因有很多&#xff0c;例如U盘驱动器问题、文件系统损坏、电脑USB接口问题等。本文将详细分析这些原因&#xff0c;并提供相应的解决方法&#xff0c;帮助用户解决无法读取U盘的问题。 如何修复无法读取的U盘&#xff0c;修复U盘的方…

一篇了解什么是Token、什么是Jwt

目录 Token什么是TokenToken实现认证流程优缺点 JWT什么是JWTJWT组成JWT加密流程优缺点 Token与JWT的区别常见的加密算法 Token 什么是Token Token: Token是访问资源接口&#xff08;API&#xff09;时所需要的资源凭证&#xff0c;也成为令牌 传统的Token 传统的Token&am…

MongoDB数据库本地部署并结合内网穿透实现navicat公网访问

文章目录 前言1. 安装数据库2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射2.3 测试随机公网地址远程连接 3. 配置固定TCP端口地址3.1 保留一个固定的公网TCP端口地址3.2 配置固定公网TCP端口地址3.3 测试固定地址公网远程访问 前言 MongoDB是一个基于分布式文件存储的数…

框架面试题

文章目录 1. spring中的bean是线程安全的吗2. 事务的实现--AOP3. 项目中用到的AOP4.spring中事务的失效场景5. Bean的生命周期6.spring中的循环引用问题7. springMVC的执行流程8. springboot自动装配原理9. 常见注解10 Mybatis11 Mybatis一二级缓存 1. spring中的bean是线程安全…

Java Web Day07-08_Layui

1. Layui概念介绍 layui&#xff08;谐音&#xff1a;类 UI) 是一套开源的 Web UI 解决方案&#xff0c;采用自身经典的模块化规范&#xff0c;并遵循原生 HTML/CSS/JS 的开发方式&#xff0c;极易上手&#xff0c;拿来即用。其风格简约轻盈&#xff0c;而组件优雅丰盈&#x…

平衡二叉树的构建(递归

目录 1.概念&#xff1a;2.特点&#xff1a;3.构建方法&#xff1a;4.代码&#xff1a;小结&#xff1a; 1.概念&#xff1a; 平衡二叉树&#xff08;Balanced Binary Tree&#xff09;&#xff0c;也称为AVL树&#xff0c;是一种二叉树&#xff0c;它满足每个节点的左子树和右…

vivado 时序多条路径

移动设置 以下示例显示了移动设置的结果&#xff1a; •示例一&#xff1a;设置5/保持相应移动 •示例二&#xff1a;设置5/保持4 示例一&#xff1a;设置5/保持相应移动 让我们假设设置路径乘数设置为五&#xff08;5&#xff09;。因为保持路径乘数是未指定&#xff0c;…

vue3 全局配置Axios实例

目录 前言 配置Axios实例 页面使用 总结 前言 Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;用于浏览器和 Node.js 环境。它提供了一种简单、一致的 API 来处理HTTP请求&#xff0c;支持请求和响应的拦截、转换、取消请求等功能。关于它的作用&#xff1a; 发起 HTTP …

消费革命:钱币新生的秘密,解锁无尽财富!

你是否曾经觉得&#xff0c;每次掏腰包后的那笔钱就此消失&#xff0c;再无踪迹&#xff1f;现在&#xff0c;我们将引领你进入一个全新的消费时代——消费革命&#xff01;它不仅满足你的物质需求&#xff0c;更将你的消费转化为财富的源泉&#xff0c;让你的每一分钱都活起来…

【网络安全/CTF】catcat-new

该题考察文件包含漏洞 正文 看到file参数&#xff0c;考虑文件读取 读取当前进程的命令行参数 ?file../../../../proc/self/cmdline读取app.py&#xff1a; bimport os\nimport uuid\nfrom flask import Flask, request, session, render_template, Markup\nfrom cat import …

Flutter详解及案例代码

概念 Flutter是由Google开发的开源UI框架&#xff0c;旨在快速构建高质量的移动应用程序。与传统的移动应用开发方式不同&#xff0c;Flutter使用单一代码库构建应用程序&#xff0c;可以同时在iOS和Android上运行。 Flutter的核心是使用Dart语言编写的&#xff0c;并且具有自…

亚马逊、虾皮、shein、Lazada等平台卖家如何冲刺圣诞大促,提升产品销量?

随着年底的临近&#xff0c;2023年的最后一个重要促销活动——圣诞大促已经冲刺阶段。 那现阶段对我们卖家来说&#xff0c;有哪些值得我们关注的点呢&#xff1f; 1.明确各级别产品的推广目的 根据产品表现&#xff0c;将产品分为主推款、平推款和清货款&#xff0c;然后针…

【adb】--- win10 配置 adb环境 超详细 (持续更新中)

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【adb】--- win10 配置 adb环境 超详细 &…

【技术分享】单网口远程透传网关快速实现昆仑通态触摸屏程序远程上下载及监控

准备工作 一台可联网操作的电脑一台单网口的远程透传网关及博达远程透传配置工具网线一条&#xff0c;用于实现网络连接和连接触摸屏一台昆仑通态触摸屏及其编程软件一张4G卡或WIFI天线实现通讯(使用4G联网则插入4G SIM卡&#xff0c;WIFI联网则将WIFI天线插入USB口&#xff0…

notepad++打开大文件失败问题

问题 :::warning 打开300多兆的日志文件提示文件太大打不开,但是其他版本的能打开 ::: 解决 换版本,没有好办法,换个版本就可以了

嵌入式科普(7)你知道JTAGSWD接口最少接几根线?

一、目的/概述 二、实际问题 2.1 原接线方式 2.2 解决方案 2.3 思考GND原因 三、资料来源 四、JTAG&SWD相关概念的逻辑 五、总结和提问 嵌入式科普(7)你知道JTAG&SWD接口最少接几根线&#xff1f; 一、目的/概述 1、那位同学直接抢答说2根线&#xff0c;数…

excel统计分析——K-S正态性检验

参考资料&#xff1a; 马兴华,张晋昕.数值变量正态性检验常用方法的对比[J].循证医学,2014,14(02):123-128 统计推断——正态性检验&#xff08;图形方法、偏度和峰度、统计&#xff08;拟合优度&#xff09;检验&#xff09;_sm.distributions.ecdf-CSDN博客 K-S检验法判断…