
🔥小龙报:个人主页
🎬作者简介:C++研发,嵌入式,机器人等方向学习者

文章目录
- 前言
- 一、创建链式结构二叉树
- 二、前中后序遍历
-
- [2.1 前序遍历](#2.1 前序遍历)
- [2.2 中序遍历](#2.2 中序遍历)
- [2.3 后序遍历](#2.3 后序遍历)
- 三、二叉树节点个数
- 四、二叉树叶子节点个数
- 五、求二叉树第k层节点个数
- 六、二叉树查找值为x的节点
- 七、层序遍历
- 八、判断是否为完全二叉树
- 总结与每日励志
前言
二叉树是数据结构中的核心内容,链式存储是其最常用的实现方式。本文围绕链式二叉树展开,从结构创建入手,详细讲解前中后序遍历、节点个数统计、叶子节点计算、层序遍历及完全二叉树判断等核心操作,结合代码实现与运行效果,帮助初学者快速掌握二叉树的基本原理与实操技巧,夯实数据结构基础。
一、创建链式结构二叉树
用链表来表示⼀棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。
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;
}

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

