C语言数据结构—二叉树的链式结构实现
目录
1、建立二叉树
1.1 二叉树的结构
1.2 手动建立二叉树
2、二叉树的遍历
2.1 二叉树的三种遍历方式
2.1.1 前序遍历
2.1.2 中序遍历
2.1.2 后序遍历
3、求二叉树的结点数和二叉树的高度
3.1 求二叉树结点数
3.2 求二叉树叶子结点
3.3 求二叉树第k层结点的个数
3.4 求二叉树的高度
4、二叉树的查找
1、建立二叉树
在学习二叉树的功能之前,先要建立二叉树,这里我们先手动建立一棵二叉树。
1.1 二叉树的结构
我们要建立的这棵二叉树,将每一个结点表示为一个结构体,每一个结点同时存储了数据和自己子结点的地址(结构体指针),如果没有子结点该指针就指向空。

typedef int BTDataType;
typedef struct BinaryTreeNode
{BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;
1.2 手动建立二叉树
使用malloc函数为结点分配空间。
为每个结点存储数据。
将新建结点插入数据这个过程封装为函数BuyNode()。
//新建结点
BTNode* BuyNode(int x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");exit(-1);}node->data = x;node->left = NULL;node->right = NULL;return node;
}
// 手动构建一棵二叉树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;
该二叉树示意图:

2、二叉树的遍历
2.1 二叉树的三种遍历方式
1、前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
2、中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之间。
3、后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。
二叉树中的核心思想是分治。所谓分治就是分分而治之,大致意思就是将一个复杂的问题转化成一个个简单的小问题,最后解决问题的思想。
2.1.1 前序遍历

1、对这棵树进行前序遍历,最原始的方法是
先访问1,然后遍历1左子树。
访问2,遍历2左子树。
访问3,遍历3左子树。
为空,再遍历3右子树。
为空,2的左子树遍历结束,再遍历2的右子树。
为空,1的左子树遍历结束,再遍历1的右子树。
…………
…………
…………
2、根据上述方法,我们可以将这个方法归纳为
先访问1后再前序遍历1的左子树和右子树,
前序遍历A的左子树 可以转化为 先访问2后再前序遍历2的左子树和右子树
前序遍历2的左子树 可以转化为 先访问3后再前序遍历3的左子树和右子树
这样就可以把一个复杂的问题转化为一个个较简单的问题。
void PrevOrder(BTNode* root)
{if (root == NULL) {printf("NULL");return;}printf("%d ", root->data);PrevOrder(root->left);PrevOrder(root->right);
}
2.1.2 中序遍历

1、对这棵二叉树进行中序遍历,最原始的方法是
先遍历1的左子树。
遍历2的左子树。
遍历3的左子树。
为空,访问3,遍历3的右子树。
为空,访问2,遍历2的右子树。
为空,访问1,遍历1的右子树。
…………
…………
…………
2、根据上述方法,我们可以将这个方法归纳为
中序遍历1的左子树后再访问1,然后中序遍历1的右子树。
中序遍历1的左子树可以转化为中序遍历2的左子树后访问2,然后中序遍历2的右子树。
中序遍历2的右子树又可以转化为中序遍历3的左子树后访问3,然后中序遍历3的右子树。
void InOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}InOrder(root->left);printf("%d ", root->data);InOrder(root->right);
}
2.1.2 后序遍历

1、对这颗二叉树进行中序遍历,最原始的方法是
先遍历1的左子树。
遍历2的左子树。
遍历3的左子树。
为空,遍历3的右子树。
为空访,访问3,遍历2的右子树。
为空,访问2,遍历1的右子树。
…………
…………
…………
2、根据上述方法,我们可以将这个方法归纳为
后序遍历1的左子树和右子树后再访问1。
后序遍历1的左子树可以转化为后序遍历2的左子树和右子树后再访问2。
后序遍历2的左子树又可以转化为后序遍历3的左子树和右子树后再访问3。
void PostOrder(BTNode* root)
{if (root == NULL){printf("NULL");return;}PostOrder(root->left);PostOrder(root->right);printf("%d ", root->data);
}
3、求二叉树的结点数和二叉树的高度
3.1 求二叉树结点数

解题思路:
1、只要该结点地址不为空就是一个结点。
2、整棵树的结点可以转化成
求1的左子树结点数加1的右子树结点树加1(自己本身也是一个结点)。
1的左子树结点树可以转化成2的左子树结点数加右子树的结点树加1。
2的左子树结点数可以转化成3的左子树结点数加D的右子树结点数加1。
3的左右子树都为空,所以2的左子树结点数为1。
…………
…………
…………
直观的写法:
int TreeSize(BTNode* root)
{if (root == NULL){return 0;}return TreeSize(root->left) + TreeSize(root->right) + 1;
}
或者简洁的写法:
int TreeSize(BTNode* root)
{return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
3.2 求二叉树叶子结点

解题思路:
1、左右孩子结点都为空的结点算作一个叶子节点。
2、求整棵树的叶子结点,可以转化为求1的左子树叶子结点和1的右子树叶子结点。
求1的左子树叶子结点可以转化为求2的左子树叶子结点加2的右子树叶子结点。
3的左右孩子结点都为空,2的左子树叶子节点为1。
…………
…………
…………
int TreeLeafSize(BTNode* root)
{if (root == NULL)return 0;if (root->left == NULL && root->right == NULL){return 1;}return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}
3.3 求二叉树第k层结点的个数

解题思路:
若k为3
1、一棵树的第一层结点为1
2、求这棵树第三层的结点数可以转化为求1的左子树以及1的右子树的第二层结点数之和。
求1的左子树的第二层结点数,可以转化成求2的左子树和2的右子树的第一层结点数之和。
2的左子树不为空,层数为1,结点数为1。
2的右子树为空,结点数为0。
…………
…………
…………
// 第k层的节点个数
int TreeKLevel(BTNode* root, int k)
{assert(k > 0);if (root == NULL)return 0;if (k == 1){return 1;}return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);}
3.4 求二叉树的高度

解题思路:
1、空树高度为0。
2、一棵树该树的根结点左右子结点都为空时,该树高度为1。
3、一棵树的高度为左右子树中高度较大的一个加1。
4、求图示中树的高度可以转化为1的左右子树中高度较大的一方加1。
求1的左子树高度可以转化为2的左右子树中高度较大的一方加1。
求2的左子树的高度可以转化为3的左右子树中高度较大的一方加1。
3的左右子结点均为空,则2的左子树高度为1。
2的右子树为空树,2的右子树高度为0,
取较大的一方加1,则2的高度为2,即1的左子树高度为2。
int TreeDepth(BTNode* root)
{if (root == NULL){return 0;}if (root->left == NULL && root->right == NULL){return 1;}return max(TreeDepth(root->left), TreeDepth(root->right));
}
4、二叉树的查找

解题思路:
假设要查找6
如果找到就返回节点地址,没找到返回空。
递归调用的时候要根据返回值来判断是否找到,如果不为空代表找到了,不需要继续查找了,这时返回节点地址。
在整颗树查找6,先看根部是否为6,不是再在1的左右子树中查找。
先看1的左子树根部是否为6,不是再在2的左右子树中查找。
先看2的左子树根部是否为6,不是再在3的左右子树中查找。
3的左右子树为空,返回空。
2的右子树为空,返回空。
1的左子树查找完毕,没找到,查找1的右子树。
先看1的右子树根部是否为6,不是再在4的左右子树查找。
先看4的左子树根部是否为6,不是再在5的左右子树中查找。
5的左右子树为空,返回空。
4的右子树为6,找到了,返回该结点地址。
BTNode* TreeFind(BTNode* root, int x)
{if (root == NULL)return NULL;if (root->data == x)return root;BTNode* ret = NULL;ret = TreeFind(root->left, x);if (ret)return ret;ret = TreeFind(root->right, x);if (ret)return ret;return NULL;
}
相关文章:
C语言数据结构—二叉树的链式结构实现
目录 1、建立二叉树 1.1 二叉树的结构 1.2 手动建立二叉树 2、二叉树的遍历 2.1 二叉树的三种遍历方式 2.1.1 前序遍历 2.1.2 中序遍历 2.1.2 后序遍历 3、求二叉树的结点数和二叉树的高度 3.1 求二叉树结点数 3.2 求二叉树叶子结点 3.3 求二叉树第k层结点的个数 …...
Java 大视界 —— Java 大数据在智能零售动态定价策略中的应用实战(98)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
如何实现修改jvm中类的属性开源项目
根据你的需求,以下是一些可以实现类似阿里巴巴 Diamond 功能的框架和工具,这些项目可以帮助你动态推送配置信息,从而实现类似的功能: 1. Nacos Nacos 是一个更现代的动态配置服务,支持配置管理、服务发现和元数据管理…...
危化品经营单位安全管理人员的职责及注意事项
危化品经营单位安全管理人员肩负着保障经营活动安全的重要责任,以下是其主要职责及注意事项: 职责 1. 安全制度建设与执行:负责组织制定本单位安全生产规章制度、操作规程和生产安全事故应急救援预案,确保这些制度符合国家相关法…...
腾讯云大模型知识引擎×DeepSeek赋能文旅
腾讯云大模型知识引擎DeepSeek赋能文旅 ——以合肥文旅为例的技术革新与实践路径 一、技术底座:知识引擎与DeepSeek的融合逻辑 腾讯云大模型知识引擎与DeepSeek模型的结合,本质上是**“知识库检索增强生成(RAG)实时联网能力”**…...
Day 49 卡玛笔记
这是基于代码随想录的每日打卡 1143. 最长公共子序列 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变…...
WebXR教学 01 基础介绍
什么是WebXR? 定义 XR VR AR Web上使用XR技术的API WebXR 是一组用于在 Web 浏览器中实现虚拟现实(VR)和增强现实(AR)应用的技术标准。它由 W3C 的 Immersive Web 工作组开发,旨在提供跨设备的沉浸式体验…...
DeepSeek+Kimi生成高质量PPT
DeepSeek与Kimi生成PPT全流程解析 一、工具分工原理 DeepSeek核心作用:生成结构化PPT大纲(擅长逻辑构建与内容优化)Kimi核心作用:将文本转换为视觉化PPT(提供模板库与排版引擎) 二、操作步骤详解 1. 通…...
hot100---day3
二叉树复习hot100专题 144. 二叉树的前序遍历 - 力扣(LeetCode) 递归法的前中后序遍历,格式比较一致; class Solution { public:vector<int>& traversal(TreeNode* root, vector<int>& ans){if(rootnullpt…...
clickhouse--表引擎的使用
表引擎决定了如何存储表的数据。包括: 数据的存储方式和位置,写到哪里以及从哪里读取数据。(默认是在安装路径下的 data 路径)支持哪些查询以及如何支持。(有些语法只有在特定的引擎下才能用)并发数据访问。索引的使用࿰…...
tauri输入js脚本的方法和注意事项initialization_script
注入js脚本最常用的就是initialization_script,通过这个方法注入的js脚本在页面每个页面都会执行,这个在tauri文档也可以搜到:WebviewWindowBuilder in tauri::webview - Rust,但是请注意,这个方法只能用在WindowBuild…...
注意力机制深度优化
###一、注意力机制深度优化 1.FlashAttentionV3(2024最新版) # 安装最新版(需H100/A100 GPU) pip install flash-attn3.0.0 --no-build-isolation# 启用FP8混合精度(需H100) model AutoModelForCausalLM.from_pretrained("…...
基于springboot的学习社区博客
一、系统架构 前端:html | bootstarp | jquery | css | ajax 后端:springboot | mybatis 环境:jdk1.8 | mysql | maven 二、代码及数据 三、功能介绍 01. web端-注册 02. web端-登录 03. web端-首页 04. web端-文章明…...
python-leetcode 42.验证二叉搜索树
题目: 给定二叉树的根节点root,判断是否是一个有效二叉搜索树 有效二叉搜索树: 1.节点的左子树只包含小于当前节点的树 2.节点的右子树只包含大于当前节点的树 3.所有左子树和右子树自身必须也是二叉搜索树 方法一:递归 如果该二叉树的…...
基于PSO-LSTM长短期记忆神经网络的多分类预测【MATLAB】
一、研究背景与意义 在时间序列分类、信号识别、故障诊断等领域,多分类预测任务对模型的时序特征捕捉能力提出了极高要求。传统LSTM网络虽能有效建模长程依赖关系,但其性能高度依赖超参数的选择,例如隐含层神经元数量、学习率、迭代次数等。…...
拓扑排序的核心算法:BFS应用与实践
目录 一、拓扑排序简介 二、BFS解决拓扑排序的步骤 三、C实现 四、代码解释 五、总结 一、拓扑排序简介 拓扑排序是对有向无环图(DAG)进行排序的一种方法,使得对于图中的每一条有向边 (u, v),u 在排序中总是位于 v 的前面。拓…...
ZLMediaKi集群设置
要在集群环境中部署 ZLMediaKit,您可以按照以下步骤进行操作。ZLMediaKit 是一个高性能的流媒体服务器,支持 RTMP、RTSP、HLS 等协议。以下是一个详细的集群部署方案: ### 1. 环境准备 - **服务器**:准备多台服务器,…...
Linux下网络运维命令总结
一、网络连通性测试 ping 作用:检测目标主机是否可达,并测量网络延迟。 示例: ping www.example.com持续发送ICMP报文,按CtrlC停止。 ping -c 4 www.example.com发送4个ICMP报文后停止。 traceroute 作用:显示数据包…...
10. 九转金丹炼矩阵 - 矩阵置零(标记优化)
哪吒在数据修仙界中继续他的修炼之旅。这一次,他来到了一片神秘的金丹谷,谷中有一座巨大的九转金丹炉,炉身闪烁着神秘的光芒。金丹炉的入口处有一块巨大的石碑,上面刻着一行文字:“欲破此炉,需以九转金丹之力,炼矩阵之零,标记优化定乾坤。” 哪吒定睛一看,石碑上还有…...
Cocos Creator Shader入门实战(一):材质和Effect的了解
引擎版本:3.8.5 环境: Windows 简介 在Cocos Creator中,游戏炫彩缤纷的效果是借助着色器(Shader)来实现的。 Cocos主要基于OpenGL ES,而Shader的编写则是在可编程渲染管线中基于修改:顶点着色器(Vertex) 和 片段着色…...
学习笔记04——JMM内存模型
一、Java内存模型(JMM)是什么? Java内存模型(Java Memory Model, JMM)是Java多线程编程中共享内存的访问规则,定义了线程如何与主内存(Main Memory)和工作内存(Work Mem…...
前端面试真题 2025最新版
文章目录 写在前文CSS怪异盒模型JS闭包闭包的形成闭包注意点 CSS选择器及优先级优先级 说说flex布局及相关属性Flex 容器相关属性:Flex 项目相关属性 响应式布局如何实现是否用过tailwindcss,有哪些好处好处缺点 说说对象的 prototype属性及原型说说 pro…...
Android 老项目 jcenter 库失效
最近重新维护了一些老项目发现大部分jcenter库失效了, Could not resolve com.xx:2.1.3. 如果你也遇到了,不妨试试 替换为 aliyun的jcenter服务,就不用一个个找代替库了。 project 下的 build.gradle 文件添加: maven { url htt…...
《论多源数据集成及应用》审题技巧 - 系统架构设计师
论多源数据集成及应用写作框架 一、考点概述 本论题“论多源数据集成及应用”主要考察的是计算机软件测试工程师在数据管理和集成方面的专业知识与实践能力。论题聚焦于信息爆炸时代企业、组织和个人所面临的数据挑战,特别是如何有效地收集、整理和清洗来自不同渠…...
2025.2.23机器学习笔记:PINN文献阅读
2025.2.23周报 一、文献阅读题目信息摘要Abstract创新点网络架构架构A架构B架构C 实验结论后续展望 一、文献阅读 题目信息 题目: Physics-Informed Neural Networks for Modeling Water Flows in a River Channel期刊: IEEE TRANSACTIONS ON ARTIFICI…...
Python Django系列—入门实例(二)
数据库配置 现在,打开 mysite/settings.py 。这是个包含了 Django 项目设置的 Python 模块。 默认情况下, DATABASES 配置使用 SQLite。如果你是数据库新手,或者只是想尝试 Django,这是最简单的选择。SQLite 包含在 Python 中…...
【DeepSeek系列】05 DeepSeek核心算法改进点总结
文章目录 一、DeepSeek概要二、4个重要改进点2.1 多头潜在注意力2.2 混合专家模型MoE2.3 多Token预测3.4 GRPO强化学习策略 三、2个重要思考3.1 大规模强化学习3.2 蒸馏方法:小模型也可以很强大 一、DeepSeek概要 2024年~2025年初,DeepSeek …...
独立开发者之Google Analytics使用教程
Google Analytics(GA)是Google提供的一款免费的网络分析服务,用于追踪和报告网站流量。以下是独立开发者如何使用Google Analytics的详细教程: 1. 创建Google Analytics账户 注册Google账户:如果你还没有Google账户&…...
C++ 编程语言简介
C 是一种通用编程语言,它是作为 C 语言的增强而开发的,以包含面向对象的范例。它是一种命令式和编译语言。 C 是一种高级的通用编程语言,专为系统和应用程序编程而设计。它由贝尔实验室的 Bjarne Stroustrup 于 1983 年开发,作为…...
计算机毕业设计SpringBoot+Vue.js明星周边产品销售网站(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
