当前位置: 首页 > news >正文

二叉树(C语言)

目录

1. 二叉树定义

2. 代码实现


1. 二叉树定义

在堆(C语言)章节我们已经了解了堆的数据结构是完全二叉树。而二叉树的定义则更加广泛,限制也比完全二叉树少:

  • 空树(节点数为0)
  • 每个节点的子节点数不超过两个

例如以下这些都是二叉树:

2. 代码实现

// 二叉树的创建会放在之后的章节进行说明,这里先临时用古法建树 >"<

代码主要采用递归的方式实现各函数功能,文件内部有详细注释:

//BinaryTree.h文件

#pragma once #include<stdlib.h> #include<math.h> #include<stdio.h> typedef int BTDataType; typedef struct BinaryTreeNode { BTDataType val; struct BinaryTreeNode* left; struct BinaryTreeNode* right; }BTNode; //新建树节点 BTNode* BuyNode(BTDataType val); //创建固定二叉树,返回根节点 BTNode* CreateBinaryTree(); //前序遍历 void PreOrder(BTNode* root); //中序遍历 void MidOrder(BTNode* root); //后序遍历 void PostOrder(BTNode* root); //计算节点个数 int TreeSize(BTNode* root); //计算叶子节点数 int LeafSize(BTNode* root); //计算树的高度 int TreeHeight(BTNode* root); //计算第K层节点个数 int LeafLevelKSize(BTNode* root, int k); //根据值查找节点 BTNode* TreeFind(BTNode* root, BTDataType x);

//BinaryTree.c文件

#include "BinaryTreeNode.h" //新建树节点 BTNode* BuyNode(BTDataType val) { BTNode* tmp = (BTNode*)malloc(sizeof(BTNode)); if(tmp == NULL) { perror("malloc fail"); exit(1); } tmp->val = val; tmp->left = NULL; tmp->right = NULL; return tmp; } //创建固定二叉树 BTNode* CreateBinaryTree() { BTNode* node1 = BuyNode(1); BTNode* node2 = BuyNode(2); BTNode* node3 = BuyNode(3); BTNode* node4 = BuyNode(4); BTNode* node5 = BuyNode(5); BTNode* node6 = BuyNode(6); node1->left = node2; node1->right = node4; node2->left = node3; node4->left = node5; node4->right = node6; return node1; } //前序遍历 void PreOrder(BTNode* root) { if(!root) return; printf("%d ", root->val); //根 PreOrder(root->left); //左 PreOrder(root->right); //右 } //中序遍历 void MidOrder(BTNode* root) { if(!root) return; MidOrder(root->left); //左 printf("%d ", root->val); //根 MidOrder(root->right); //右 } //后序遍历 void PostOrder(BTNode* root) { if(!root) return; PostOrder(root->left); //左 PostOrder(root->right); //右 printf("%d ", root->val); //根 } //计算节点个数 int TreeSize(BTNode* root) { if(!root) return 0; //左子树节点数 + 右子树节点数 + 当前节点 return TreeSize(root->left) + TreeSize(root->right) + 1; } //计算叶子节点数 int LeafSize(BTNode* root) { //要考虑root为空的情况!否则会报错 if(!root) return 0; //左右都为空,即为叶子节点 if(!root->left && !root->right) return 1; return LeafSize(root->left) + LeafSize(root->right); } //计算树的高度 int TreeHeight(BTNode* root) { if(!root) return 0; //取左右子树中较深的一棵,算入当前层数 return fmax(TreeHeight(root->left), TreeHeight(root->right)) + 1; } //计算第K层节点个数 int LeafLevelKSize(BTNode* root, int k) { if(!root) return 0; //到达K层则将当前节点计入总数 if(k == 1) return 1; return LeafLevelKSize(root->left, k-1) + LeafLevelKSize(root->right, k-1); } //根据值查找节点 BTNode* TreeFind(BTNode* root, BTDataType x) { if(!root) return NULL; if(root->val == x) return root; BTNode* ret1 = TreeFind(root->left, x); if(ret1 != NULL) { return ret1; //找到就return,不必遍历右子树 } BTNode* ret2 = TreeFind(root->right, x); if(ret2 != NULL) { return ret2; } return NULL; //注意不要漏掉if条件之外的return! }

这里附上一个测试文件:

#include "BinaryTreeNode.h" #include "BinaryTreeNode.c" int main() { BTNode* root = CreateBinaryTree(); PreOrder(root); printf("\n"); MidOrder(root); printf("\n"); PostOrder(root); printf("\n"); int size = TreeSize(root); printf("树的节点个数为%d个。\n", size); int leaf = LeafSize(root); printf("树的叶子节点个数为%d个。\n", leaf); int height = TreeHeight(root); printf("树的高度为%d。\n", height); int k = 0; printf("树的高度为%d,请输入你要查询的层数:\n", height); scanf("%d", &k); int LevelKNode = LeafLevelKSize(root, k); printf("第%d层的节点数为%d。\n", k, LevelKNode); int FindVal = 0; printf("请输入你要查找的值:\n"); scanf("%d", &FindVal); BTNode* FindOut = TreeFind(root, FindVal); if(!FindOut) { printf("没有找到。\n"); } else { printf("找到了。\n"); } return 0; }

// 感谢阅读~( ̄︶ ̄)↗

http://www.jsqmd.com/news/605520/

相关文章:

  • 从零开始构建嵌入式安全:OP-TEE可信执行环境实战指南
  • Creo混合与扫描混合实战:从基础到高级建模技巧
  • 跨平台文件同步:OpenClaw调用Gemma-3-12b-it智能分类备份方案
  • IHaskell实战案例:利用梯度下降算法解决实际优化问题的完整演示
  • AI 设计模式 04:多智能体协作模式 —— 给 AI 组个团队,干活比你公司的人还利索
  • 光电对抗:激光与激光雷达成像探测制导及电子对抗(2)
  • OpenClaw版本升级:无缝迁移Kimi-VL-A3B-Thinking配置到新版本
  • Qwen3-Reranker-0.6B镜像部署:开箱即用的RAG重排序服务容器化方案
  • GDScriptDecomp源码编译指南:从零构建自定义逆向工程工具
  • 从H.264到AV1:主流视频编码标准的演进、选型与实战场景剖析
  • 正则表达式基础
  • Phi-4-mini-reasoning教程:用HuggingFace pipelines封装标准化推理流水线
  • 光电对抗:激光与激光雷达成像探测制导及电子对抗(3)
  • 链表(两数相加)(1)
  • OpenClaw二次开发入门:Phi-3-mini-128k-instruct模型适配改造
  • Python脚本打包成.exe方法
  • RTX4090D显存优化:Qwen3-32B-Chat镜像并发处理OpenClaw任务实测
  • 基于单片机的的公交车报站系统(有完整资料)
  • Ostrakon-VL-8B商业应用:赋能区域督导远程巡店,替代80%人工拍照核查
  • LabVIEW调用HTTPS接口的保姆级教程:从抓取CA证书到GET请求一气呵成
  • Simufact.Forming工艺链仿真实战:从冷成型到热处理的完整流程配置技巧
  • Phi-4-mini-reasoning轻量推理:模型剪枝后4.2GB版本在A10G上的部署实测
  • Mac环境OpenClaw排错大全:Qwen3.5-9B接口调用常见问题
  • 关键词扩词软件怎么做竞争分析_关键词扩词软件对网站SEO有什么帮助
  • 手把手教你用Xilinx Artix7 FPGA实现千兆以太网通信(GMII接口实战)
  • 2026年防水防潮隔墙板厂家排行:环保轻质隔墙板/聚苯颗粒板/轻质保温隔墙板/防火隔墙板/预制板/预制构件/预制隔墙板/选择指南 - 优质品牌商家
  • Fish Speech 1.5语音自然度提升指南:标点映射规则、停顿时长微调、重音标注
  • 快速验证机器人抓取创意:用快马平台十分钟搭建OpenClaw仿真原型
  • FPGA工程师面试资料【8】——时序约束方法
  • 文本处理实战