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

🔥小龙报:个人主页

🎬作者简介: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;
}

总结与每日励志

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

相关推荐
叠层归一研究院2 分钟前
如何用程序搭建一个 AGI 种子系统(一):从向量种子到无限生长引擎
人工智能·python·算法·机器学习·agi
名不经传的养虾人2 分钟前
从0到1:企业级AI项目迭代日记 Vol.87|记忆链路切换了,系统接管有了质量门
大数据·人工智能·ai编程·企业ai·多agent协作
GlobalInfo3 分钟前
2026年显微外科手术机器人系统市场报告:市场规模、产业研究、十五五规划与发展趋势预测
大数据·人工智能·机器人
神奇小汤圆6 分钟前
DeepSeek Harness 的基石:从源码理解 Cordis
人工智能
Leslie16521 分钟前
模型调价之后,如何把 Token 账单变成可回滚的预算策略
人工智能
企鹅的企23 分钟前
2027北京AI健康科技与智慧医疗展官方链接产业资源
人工智能·科技
步行cgn25 分钟前
MyBatis Error evaluating expression ‘ids‘. Return value (3) was not iterable 错误详
java·后端
yujunl27 分钟前
总结一下U9客开的成果
开发语言
独隅28 分钟前
KMP 全栈进化:Koog 框架打造纯 Kotlin AI Agent 实战效果
开发语言·人工智能·kotlin
zhy2956331 分钟前
【DNN】Llama 3.2 1B模型LORA微调与QAIRT部署
人工智能·dnn·llama