【数据结构与算法】一文拿捏链式二叉树:遍历 + 统计 + 层序 + 完全树

🔥小龙报:个人主页

🎬作者简介:C++研发,嵌入式,机器人等方向学习者

❄️个人专栏:《C语言》《数据结构与算法》
✨ 永远相信美好的事情即将发生



文章目录


前言

二叉树是数据结构中的核心内容,链式存储是其最常用的实现方式。本文围绕链式二叉树展开,从结构创建入手,详细讲解前中后序遍历、节点个数统计、叶子节点计算、层序遍历及完全二叉树判断等核心操作,结合代码实现与运行效果,帮助初学者快速掌握二叉树的基本原理与实操技巧,夯实数据结构基础。


一、创建链式结构二叉树

用链表来表示⼀棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。

html 复制代码
typedef struct BinaryNode
{
    BinaryDataType x;
    struct BTNode* left; //左孩子
    struct BTNode* right; //右孩子

}BTNode;

注:我们为了方便后续的使用,先手动创建一颗链式二叉树

html 复制代码
BTNode* CreatTree()
{
	BTNode* nodeA = buyNode('A');
	BTNode* nodeB = buyNode('B');
	BTNode* nodeC = buyNode('C');
	BTNode* nodeD = buyNode('D');
	BTNode* nodeE = buyNode('E');
	BTNode* nodeF = buyNode('F');

	nodeA->left = nodeB;
	nodeA->right = nodeC;
	nodeB->left = nodeD;
	nodeC->left = nodeE;
	nodeC->right = nodeF;

	return nodeA;
}

二、前中后序遍历

  1. 前序遍历(先根遍历) :先遍历根节点,再遍历左子树,最后遍历右子树----根左右
  2. 中序遍历 :先遍历左子树,再遍历根节点,最后遍历右子树----左根右
  3. 后续遍历 :先遍历左子树,再遍历右子树,最后遍历根节点----左右根

2.1 前序遍历

规则 :根左右

html 复制代码
// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	//根左右
	printf("%c ", root->x);
	BinaryTreePrevOrder(root->left);
	BinaryTreePrevOrder(root->right);

}

运行结果 :

遍历顺序图:

这里红线统一表示递归,另一个表示回退

函数递归栈栈图 :(标的序号表示打印的顺序)

2.2 中序遍历

规则:左根右

html 复制代码
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	//左根右
	BinaryTreeInOrder(root->left);
	printf("%c ", root->x);
	BinaryTreeInOrder(root->right);
}

运行结果 :

函数递归栈栈图:(标的序号表示打印的顺序)

2.3 后序遍历

规则:左右根

html 复制代码
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	//左右根
	BinaryTreePostOrder(root->left);
	BinaryTreePostOrder(root->right);
	printf("%c ", root->x);
}

运行结果 :

函数递归栈栈图 :(标的序号表示打印的顺序)

三、二叉树节点个数

二叉树结点个数=根节点+左子树结点个数+右子树结点个数

运行结果 :

四、二叉树叶子节点个数

二叉树的叶子节点就是左右孩子都为空的节点

公式 :
二叉树叶子节点个数=左子树叶子节点个数+右子树叶子节点个数

html 复制代码
// 二叉树叶子节点个数:左子树叶子节点个数+右子树节点个数
int BinaryTreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;

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

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

运行结果:

五、求二叉树第k层节点个数

公式 :二叉树第k层节点个数=左子树第k-1层节点个数+右子树第k-1层节点个数

html 复制代码
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)
		return 0;

	if (k == 1)
		return 1;
	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

运行结果 :

六、二叉树查找值为x的节点

递归查找,找到了就返回当前节点,如果是在左子树中找到就直接返回,没找到继续来到右子树找,最好都没找到就返回NULL

七、层序遍历

准备工作 :

1.我们需要先把队列的.c和.h文件导入到当前vs项目中,然后在Tree.c文件里面包含上Queue.h文件


前置声明 :

html 复制代码
//二叉树的层序遍历
void LevelOrder(BTNode* root)
{
	Queue q;
    QueueInit(&q); //初始化队列
    QueuePush(&q, root); //根节点入队
	while (!QueueIsEmpty(&q))
	{
       BTNode* front = QueueFront(&q);
       printf("%c ", front->x);
       QueuePop(&q);
       if (front->left) //左子树入队
           QueuePush(&q, front->left);
       if (front->right) //右子树入队
           QueuePush(&q, front->right);
	}

	QueueDestroy(&q); //销毁队列
}

运行结果 :

图解 :

八、判断是否为完全二叉树

html 复制代码
//判断是否为完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	//根节点入队
	QueuePush(&q, root);

	//遍历
	while (!QueueIsEmpty(&q))
	{
		//取队首,然后出队首
		BTNode* top = QueueFront(&q);
		QueuePop(&q);
		if (top == NULL)
		{
			//top取到空直接出队列
			break;
		}
		//将top的左右孩子节点全部入队
		QueuePush(&q, top->left);
		QueuePush(&q, top->right);
	}

	//队列不为空,继续取队列中的队头
	while (!QueueIsEmpty(&q))
	{
		BTNode* top = QueueFront(&q);
		if (top != NULL)
		{
			//有不是NULL的就不是完全二叉树
			QueueDestroy(&q);
			return false;
		}
		QueuePop(&q);
	}
	QueueDestroy(&q);
	return true;
}

总结与每日励志

✨ 本文完整覆盖链式二叉树的创建、遍历、各类节点统计及完全二叉树判断等关键知识点,核心是递归思想与队列工具的灵活运用。学习二叉树需多练多思考,正视每一个报错与疑问。愿你在数据结构的学习路上,不慌不忙、循序渐进,把每一个知识点吃透,把每一行代码写扎实。永远相信美好的事情即将发生,坚持下去,终会收获成长与突破!

相关推荐
Csvn10 小时前
第 28 章 案例四 多智能体协作系统
人工智能·aigc·agent
IT_陈寒10 小时前
Java中equals方法比了个寂寞?原来这才是正确的重写姿势
前端·人工智能·后端
IT枫斗者枫哥10 小时前
MyBatis一对多分页:LIMIT 20,为什么凑不齐20个订单?
java·数据库
吴佳浩10 小时前
Agent 怎么做自动化评测?构建端到端的 Agent Evaluation 体系
人工智能·agent·ai编程
火山引擎开发者社区10 小时前
火山引擎云数据库 TiDB 版公测开启,MySQL 架构升级的一站式选择
人工智能
代码方舟10 小时前
Java数据工程:利用天远全网运营商三要素优化线上实名认证合规体验
java·人工智能
Csvn10 小时前
第 27 章 案例三 自动化工作流 Agent
人工智能·aigc·agent
知几蜗牛10 小时前
AI眼镜把记忆放上云,怎样证明云端也看不见?
人工智能
知几蜗牛10 小时前
训练数据越多越好吗?用LeRobot讲清数据质量与版本化
人工智能
BBmmo10 小时前
我的 Java 学习笔记 · 第 7 篇:泛型与通配符
java