二叉树的遍历(节点个数及层序遍历)

news2025/6/18 5:49:21

 简易树的图形:

 

#include <stdio.h>
#include  <stdlib.h>

//重定义数据类型
typedef char DataType;
//创建简易的二叉树结构体
typedef struct BTNode
{
	struct BTNode* left;
	struct BTNode* right;
	DataType data;
}BTNode;
//前序(根左右)
void Prev(BTNode* root)
{
	//判空
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%c ", root->data);
	Prev(root->left);
	Prev(root->right);
}
//中序(左根右)
void Inmid(BTNode* root)
{
	//判空
	if (root == NULL)
	{
		printf("NULL ");
		return 0;
	}
	Inmid(root->left);
	printf("%c ", root->data);
	Inmid(root->right);
}
//后序(左右根)
void Pose(BTNode* root)
{
	//判空
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	Pose(root->right);
	printf("%c ", root->data);
	Pose(root->left);
}
//返回节点个数
int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
//初始化以及赋值树
int main()
{
	BTNode* A = (BTNode*)malloc(sizeof(BTNode));
	A->left = NULL;
	A->right = NULL;
	A->data = 'A';
	BTNode* B = (BTNode*)malloc(sizeof(BTNode));
	B->left = NULL;
	B->right = NULL;
	B->data = 'B';
	BTNode* C = (BTNode*)malloc(sizeof(BTNode));
	C->left = NULL;
	C->right = NULL;
	C->data = 'C';
	BTNode* D = (BTNode*)malloc(sizeof(BTNode));
	D->left = NULL;
	D->right = NULL;
	D->data = 'D';
	BTNode* E = (BTNode*)malloc(sizeof(BTNode));
	E->left = NULL;
	E->right = NULL;
	E->data = 'E';
	//赋值
	A->data = 'A';
	A->left = B;
	A->right = C;
	B->data = 'B';
	B->left = D;
	B->right = E;
	/*Prev(A);
	printf("\n");
	Inmid(A);
	printf("\n");*/
	printf("TreeSize:%d\n", TreeSize(A));
	printf("TreeSize:%d\n", TreeSize(B));
	return 0;
}

 运行实例:

以A节点开始运算的节点个数

以B节点开始运算的节点个数

解释(图解+文字解释): 

把A传过去A不为空,进入left,A的left为B不为空,B的left为D不为空,D的left和right都为空返回0+0+1,在进入B的right,B的right为E不为空,E的left和right都为空返回0+0+1,B的left和right都返回1,运行完B,B再返回1+1+1=3,再进入A right->C,Cleft,right都为空返回1,最后A返回left(3)+right(1)+1=5.

 

 求叶子节点个数:

//叶子节点的个数
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);
}

 传A过去,先判断A不为空,也不为叶子,则返回A的left+right,进入left为B,不为空和叶子,返回B的left和right,进入B left为D为叶子返回1,再进入B的right为E叶子返回1,则B返回2,在进入A的right C,C为叶子返回1,最终A返回3.

 


注意:(计算节点麻烦的用法)

1.定义全局变量来统计

因为要每次把size归零比较麻烦

 

 

 2.传地址

传地址过去然后每次遇见一个节点++

 

 

 


 层序遍历法:(符合队列的先进先出)

概念:及从第一行开始,一行一行的统计,每行从左到右,如我们最开始的例图层序遍历完后为ABCDE。

举例解释:

 

 

 

 讲解:先代入A,A不为空,拿出A且代入A的子节BC,B不为空,拿出B再代入B的子节DE,C不为空拿出C再代入C的子节FG,D不为空拿出(D没有子节不用带入了),E不为空拿出,代入E的子节H,FGH都不为空且都没有子节了再依次拿出到空为止。

实现:

 头文件:

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//前置声明(防止头文件Quene.h在2复制过去后往上找的时候找不到我们创建的树的结构体BTNode)
struct BTNode;

//重命名类型
typedef struct BTNode* QDataType;
//创建队列结构体
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;
//创建指针
typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;

//初始化
void QueueInit(Queue* pq);
//销毁
void QueueDestory(Queue* pq);
//队尾入队列
void QueuePush(Queue* pq,QDataType x);
//队头出队列
void QueuePop(Queue* pq);
//取数据队头
QDataType QueueFront(Queue* pq);
//取数据队尾
QDataType QueueBack(Queue* pq);
//数据的有效值
int QueueSize(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);

队列文件:

#include "Queue.h"

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}
//销毁
void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur=pq->head;
	while (cur)
	{
		QNode* next = cur->next;//先保存下一个再释放自己,再让next赋值给cur
		free(cur);
		cur = next;
	}
	//结束后再把head和tail置空
	pq->head = pq->tail = NULL;
}
//队尾入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	else
	{
		newnode->data = x;
		newnode->next = NULL;
	}
	if (pq->tail==NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}
//队头出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	if (pq->head->next == NULL)//这里我们要判断一下head的next是否为空,如果为空说明只有一个节点了,我们直接释放,否则tail变成了野指针
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
//取数据队头
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);//先判断头是否已经为空
	return pq->head->data;
}
//取数据队尾
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	return pq->tail->data;
}
//数据的有效值
int QueueSize(Queue* pq)
{
	assert(pq);
	int size = 0;
	QNode* cur = pq->head;
	while (cur)//我们直接遍历一遍知道cur为空的时候停止
	{
		size++;
		cur = cur->next;
	}
	return size;
}
//判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;//判断如果为空则返回真,否则为假
}

树文件

#include <stdio.h>
#include  <stdlib.h>
#include "Queue.h"
//重定义数据类型
typedef char DataType;
//创建简易的二叉树结构体
typedef struct BTNode
{
	struct BTNode* left;
	struct BTNode* right;
	DataType data;
}BTNode;
//前序(根左右)
void Prev(BTNode* root)
{
	//判空
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%c ", root->data);
	Prev(root->left);
	Prev(root->right);
}
//中序(左根右)
void Inmid(BTNode* root)
{
	//判空
	if (root == NULL)
	{
		printf("NULL ");
		return 0;
	}
	Inmid(root->left);
	printf("%c ", root->data);
	Inmid(root->right);
}
//后序(左右根)
void Pose(BTNode* root)
{
	//判空
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	Pose(root->right);
	printf("%c ", root->data);
	Pose(root->left);
}
//返回节点个数
int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 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);
}
//层序遍历
void LevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)//如果队列为空则入值
		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);
		}
	}
	printf("\n");
	QueueDestory(&q);
}
//初始化以及赋值树
int main()
{
	BTNode* A = (BTNode*)malloc(sizeof(BTNode));
	A->left = NULL;
	A->right = NULL;
	A->data = 'A';
	BTNode* B = (BTNode*)malloc(sizeof(BTNode));
	B->left = NULL;
	B->right = NULL;
	B->data = 'B';
	BTNode* C = (BTNode*)malloc(sizeof(BTNode));
	C->left = NULL;
	C->right = NULL;
	C->data = 'C';
	BTNode* D = (BTNode*)malloc(sizeof(BTNode));
	D->left = NULL;
	D->right = NULL;
	D->data = 'D';
	BTNode* E = (BTNode*)malloc(sizeof(BTNode));
	E->left = NULL;
	E->right = NULL;
	E->data = 'E';
	//赋值
	A->data = 'A';
	A->left = B;
	A->right = C;
	B->data = 'B';
	B->left = D;
	B->right = E;
	/*Prev(A);
	printf("\n");
	Inmid(A);
	printf("\n");*/
	printf("TreeSize:%d\n", TreeSize(A));
	printf("TreeSize:%d\n", TreeSize(B));
	LevelOrder(A);
	return 0;
}

 

 

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

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

相关文章

2023年股票代持行业研究报告

第一章 股票代持概述 1.1 基本概念 股票代持&#xff0c;或称委托持股&#xff0c;是指实际出资人与名义出资人达成以下约定&#xff1a;名义出资人作为名义股东&#xff0c;在股东名册等公司工商登记信息上出现&#xff0c;而实际上由实际出资人出资并享有投资权益。 股票代…

WPF MVVM模式构建项目

什么是MVVM模式&#xff1f; MVVM是Model-View-ViewModel的简写&#xff0c;Model就是模型&#xff0c;View就是视图&#xff0c;ViewModel就是View和Model之间解耦和传递消息的中间层。MVVM采用双向数据绑定&#xff0c;View中数据变化将自动反映到ViewModel上&#xff0c;反之…

【并发编程】异步编程CompletableFuture实战

文章目录1.CompletableFuture简介2.CompletableFuture核心API实战3.CompletableFuture嵌套案例实战4.合并两个CompletableFuture案例实战5.多个CompletableFuture任务组合调度实战1.CompletableFuture简介 在JDK8之前&#xff0c;我们使用的Java多线程变成&#xff0c;主要是 …

Golang GORM入门

一、GORM入门 1.1 什么是ORM&#xff1f; orm是一种术语而不是软件 orm英文全称object relational mapping&#xff0c;就是对象映射关系简单来说类似python这种面向对象的程序来说一切皆对象&#xff0c;但是我们使用的数据库却都是关系型的 为了保证一致的使用习惯&#xff…

NumPy 数组学习手册:1~5

原文&#xff1a;Learning NumPy Array 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 一、NumPy 入门 让我们开始吧。 我们将在不同的操作系统上安装 NumPy 和相关软件&#xff0c;并查看一些使用 NumPy 的简单代码。 正如“序言”所述&#xff0c;SciPy 与 NumPy 密…

开放式蓝牙耳机推荐,推荐几款具有代表性的骨传导耳机

骨传导耳机是一种骨传导技术和音频技术结合的产品&#xff0c;通过声音将振动从骨头传到听觉神经&#xff0c;从而达到听音的效果。相比于传统的入耳式耳机&#xff0c;骨传导耳机佩戴更舒适&#xff0c;不会对耳朵造成损伤。然而市面上有很多不同类型的骨传导耳机&#xff0c;…

机器学习和深度学习在气象中的应用(台风预报只能订正、风速预报订正、LSTM 方法预测 ENSO)

查看原文>>>Python人工智能在气象中的实践技术应用 目录 专题一、Python 和科学计算基础 专题二、机器学习和深度学习基础理论和实操 2.1 机器学习和深度学习基础理论 2.2 sklearn 和pytorch 库 专题三 、气象领域中的机器学习应用实例 3.1 GFS 数值模式的风速…

【玩转RT-Thread】RT-Thread网络框架:BSD网络接口SAL套接字抽象层

文章目录RT-Thread网络框架&#xff1a;BSD网络接口&SAL套接字抽象层基础知识1.TCP与UDP的区别2.TCP编程 服务端配置过程3.TCP编程 客户端配置过程4.UDP编程 客户端配置过程SAL套接字抽象层1.SAL组件主要功能特点&#xff1a;2.SAL网络框架3.工作原理4.多协议接入与接口函数…

“成年人”的数据库,既要又要也要!

欢迎访问 OceanBase 官网获取更多信息&#xff1a;https://www.oceanbase.com/ 3 月 25 日&#xff0c;第一届 OceanBase 开发者大会在北京举行&#xff0c;《明说三人行》访谈栏目创始人兼主持人卢东明、沃趣科技创始人兼 CEO 陈栋、DBAplus 社群联合创始人杨建荣、PostgreSQL…

7.1 基本运算电路(2)

七、集成运放性能指标对运算误差的影响 在上述各电路运算关系的分析中&#xff0c;均认为集成运放为理想运放。而实际上&#xff0c;当利用运放构成运算电路时&#xff0c;由于开环差模增益 AodA_{od}Aod​、差模输入电阻 ridr_{id}rid​ 和共模抑制比 KCMRK_{CMR}KCMR​ 为有…

【计算机网络-应用层】域名系统 DNS、文件传输协议 FTP、电子邮件

文章目录1 域名系统 DNS1.1 域名结构1.2 域名服务器1.2.1 根域名服务器1.2.2 顶级域名服务器1.2.3 权限域名服务器1.2.4 本地域名服务器1.3 域名解析过程1.3.1 递归查询1.3.2 递归与迭代相结合查询1.3.3 本地域名服务器的高速缓存2 文件传输协议 FTP2.1 主动模式&#xff08;建…

java编译和运行带有包名的类

写在前面 对于习惯了使用ide的我们似乎早已经忘记了如何通过命令行来编译和运行java类了&#xff0c;至少我是这样的&#xff0c;本文就一起来回顾下吧&#xff01; 1&#xff1a;运行不带包的类 这种相信大多数朋友都记得&#xff0c;直接javac yourCode.java,然后java you…

Camtasia studio2023录屏和后期剪辑的软件

Camtasia 2023是专门用于屏幕录制的软件&#xff0c;功能十分丰富&#xff0c;不仅可以录制电脑屏幕、局部区域和摄像头等&#xff0c;而且还能即时编辑视频&#xff0c;给视频添加转场、旁白、字幕等&#xff0c;能够轻松制作更优秀的视频。 兼顾录屏和后期剪辑的软件—Camtas…

Oracle_EBS_核心功能(MFG)(第二部分)

BOM: Routing工艺路线应用&#xff1a;Bills of Material 职责&#xff1a;Bills of Material 基础业务学习总体说明 Routing&#xff08;工艺路线&#xff09;最终解决的问题是生产过程中加工顺序、资源和用量的标准化。准确度要求在98%以上&#xff0c;要不断与现场比对&…

【离散数学】图论

1、有n个点没有边 零图 2、有1个点没有边 平凡图 3、含有平行边的图 多重图 4、简单图 不含有平行边和自回环的图 5、任意两个结点之间都有边 完全图 6、环贡献 两度 7、所有顶点的度数之和等于边数的两倍 8、在有向图中所有顶点的出度之和 或者 入度之和 等于边数 9、度数为…

特斯拉和OpenAI的加持,马斯克简直人生赢家

赢家已定 商人行事&#xff0c;最重要的因素之一是利益驱动。这里&#xff0c;最服“马斯克”。 以马斯克为首的特斯拉公司周日宣布&#xff0c;将在上海新建一家超级工厂&#xff0c;专门生产该公司的储能产品Megapack。签约的特斯拉储能超级工厂项目也是该公司在美国本土以…

【论文笔记】CRN: Camera Radar Net for Accurate, Robust, Efficient 3D Perception

原文链接&#xff1a;https://arxiv.org/abs/2304.00670 1. 引言 本文提出两阶段融合方法CRN&#xff0c;能使用相机和雷达生成语义丰富且位置精确的BEV特征。具体来说&#xff0c;首先将图像透视特征转换到BEV下&#xff0c;该步骤依赖雷达&#xff0c;称为雷达辅助的视图变换…

大数据技术(入门篇) --- centos7安装CDH6.2集群

随着信息化时代的进步&#xff0c;业务系统的数据量出现了爆发式的增长&#xff0c;带来的不良结果就是数据库的数据量剧增&#xff0c;而部分业务系统需要实时数据&#xff0c;有些业务系统需要离线计算后的数据&#xff0c;所以就产生了大数据技术&#xff0c;因此最近在学习…

面试官:说一说mysql的varchar字段最大长度?

在mysql建表sql里&#xff0c;我们经常会有定义字符串类型的需求。 CREATE TABLE user (name varchar(100) NOT NULL DEFAULT COMMENT 名字 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 ;比方说user表里的名字&#xff0c;就是个字符串。mysql里有两个类型比较适合这个场景。 ch…

剧本拆分如何用ai人工智能辅助完成

随着现代技术的发展&#xff0c;人工智能在电影制作领域中的应用已经越来越普遍。其中&#xff0c;辅助剧本拆分是人工智能技术的一种重要应用。人工智能可以帮助电影制作人员更快速、更准确地进行剧本拆分&#xff0c;提高制作效率和创作质量。 剧本拆分是电影制作中非常重要的…