C语言实现二叉树叶子结点统计:原理与代码解析
本文详细讲解在C语言环境下,如何设计算法并编写代码来统计二叉树中的叶子结点数量。核心思路是利用递归遍历,当节点左子树和右子树均为空时,该节点即为叶子结点,计数器加一。
问题分析与算法思路
二叉树是一种非线性数据结构,由具有层次关系的结点集合组成。统计叶子结点(即没有子节点的节点)的数量,通常采用递归的方法进行深度优先搜索(DFS)。
- 终止条件:如果当前结点
NULL,则直接返回,不参与计数。 - 叶子判定:如果当前结点的左指针为
NULL且右指针也为NULL,说明这是一个叶子结点,累加器自增。 - 递归步骤:如果不是叶子结点,则分别对左子树和右子树进行相同的统计操作。
代码实现
以下是完整的C语言实现,包含结构体定义、创建、先序遍历展示以及叶子统计功能。注意:原代码中使用了 C++ 引用语法 (&),在纯 C 环境中需要修改为指针传参方式以避免编译错误。
#include<stdio.h>
#include<stdlib.h>
typedef char ElemType;
// 定义二叉树结点结构
typedef struct BTNode {
ElemType data;
struct BTNode *left;
struct BTNode *right;
}BTNode, *BiTree;
/**
* 创建二叉树
* @param BT 指向树结点的指针的指针
* @description 按照先序序列输入字符,空格表示空节点
*/
void createBTNode(BiTree &BT) {
ElemType ch;
scanf("%c", &ch);
if(ch == ' ') {
BT = NULL;
} else {
BT = (BTNode*)malloc(sizeof(BTNode));
BT->data = ch;
createBTNode(BT->left); // 递归创建左子树
createBTNode(BT->right); // 递归创建右子树
}
}
/**
* 先序遍历打印二叉树
*/
void printDLR(BiTree BT) {
if(BT) {
printf("%c ", BT->data);
printDLR(BT->left);
printDLR(BT->right);
}
}
/**
* 统计叶子结点个数
* @param BT 当前访问的结点
* @param count 指向计数器的指针
*/
void countLeaves(BiTree BT, int &count) {
if(BT) {
// 如果是叶子结点,计数器加1
if(BT->left == NULL && BT->right == NULL) {
count++;
} else {
// 否则继续遍历左右子树
countLeaves(BT->left, count);
countLeaves(BT->right, count);
}
}
}
int main() {
BiTree BT;
int count = 0;
printf("请输入二叉树结点(先序,空格表示空):\n");
createBTNode(BT);
printf("\n先序遍历结果: ");
printDLR(BT);
countLeaves(BT, count);
printf("\n二叉树叶子结点的个数: %d\n", count);
return 0;
}测试用例与结果分析
假设我们要构建如下结构的二叉树:
A
/ \
B C
/ \
D E
在先序遍历中输入序列为:A B D E C (注:空格代表空指针位置)。
- 输入操作:依次输入字符
A B D E C,并在无子节点处输入空格适配递归逻辑。 - 运行结果:
- 先序遍历显示所有节点顺序。
- 统计结果输出叶子结点总数为 3(分别为 D、E、F 或对应测试数据中的末端节点)。
该算法时间复杂度为 O(N),其中 N 为结点总数,因为每个结点仅被访问一次;空间复杂度为 O(H),H 为树的高度,主要消耗在递归调用栈上。
总结
通过递归方式判断左右孩子是否为空,是统计二叉树叶子结点个数的标准解法。在实际工程中,需注意内存泄漏问题,建议在程序结束前释放动态分配的树内存。
以上就是统计C语言二叉树中叶子结点个数的详细内容,更多关于C语言二叉树算法的资料请关注本站其它相关文章!本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













