数据结构( 二叉树)
⚙️第一部分Makefile 基本操作详解1.1 什么是 MakefileMakefile 是一个自动化构建工具make的配置文件。它描述了项目中各个源文件之间的依赖关系以及如何编译和链接生成最终的可执行文件。在大中型 C/C 项目中手动输入gcc main.c func.c -o app不仅繁琐而且每次修改一个文件就要重新编译所有文件效率低下。Makefile 能够只重新编译被修改过的文件从而大幅节省构建时间。1.2 Makefile 的核心规则Makefile 由一条条规则组成每条规则的基本格式为目标(target): 依赖(prerequisites) [Tab] 命令(recipe)目标 (target)要生成的文件名通常是一个可执行文件或一个.o文件。依赖 (prerequisites)生成目标所需要的源文件或其他目标。命令 (recipe)实际执行的编译指令必须以一个 Tab 键开头不能用空格。当make执行时它会比较目标文件和依赖文件的修改时间。如果依赖比目标新或者目标不存在则执行命令重新生成目标。1.3 一个简单的 Makefile 示例假设项目包含main.c、queue.c、queue.h最终的 Makefile 可以这样写# 定义变量习惯上使用大写 CC gcc CFLAGS -Wall -g TARGET app OBJS main.o queue.o 链接目标将所有 .o 文件链接成可执行文件 $(TARGET): $(OBJS) $(CC) $(CFLAGS) $^ -o $ 编译规则每个 .c 文件单独编译成 .o 文件 main.o: main.c queue.h $(CC) $(CFLAGS) -c main.c -o main.o queue.o: queue.c queue.h $(CC) $(CFLAGS) -c queue.c -o queue.o 清理目标 clean: rm -f $(OBJS) $(TARGET)变量说明CC指定 C 编译器。CFLAGS编译选项。-Wall显示所有警告-g生成调试信息。$自动化变量代表目标文件。$^自动化变量代表所有依赖文件。$自动化变量代表第一个依赖文件。1.4 使用通配符简化 Makefile当源文件很多时可以使用通配符和模式规则来简化书写CC gcc CFLAGS -Wall -g TARGET app SRCS $(wildcard *.c) # 查找当前目录下所有 .c 文件 OBJS $(SRCS:.c.o) # 将 .c 替换为 .o $(TARGET): $(OBJS) $(CC) $(CFLAGS) $^ -o $ 模式规则将所有 .c 文件编译成对应的 .o 文件 %.o: %.c $(CC) $(CFLAGS) -c $ -o $ clean: rm -f $(OBJS) $(TARGET)关键点解析wildcard函数用于获取匹配的文件列表。$(SRCS:.c.o)是一种替换引用将列表中所有.c后缀替换为.o。%.o: %.c是一条模式规则表示任意一个.o文件都依赖于同名的.c文件。这样就不需要为每个文件单独写规则了。1.5 Makefile 中的常用命令与注意事项make默认执行第一个目标通常为all或直接是最终目标。make clean执行clean目标清理编译产物。.PHONY声明伪目标确保即使当前目录存在名为clean的文件make clean依然会执行命令。命令前加可以静默执行不显示命令本身如echo Building...。核心价值掌握 Makefile 意味着你能够高效地管理任何规模的 C/C 项目理解 IDE 底层构建原理并具备独立排查编译链接错误的能力。第二部分二叉树与遍历2.1 二叉树的基本概念二叉树是一种树形结构每个节点最多有两个子节点左孩子left child和右孩子right child。二叉树是计算机科学中最重要的数据结构之一广泛应用于表达式解析、搜索算法二叉搜索树、堆、哈夫曼编码等场景。根节点root树的最顶层节点没有父节点。叶子节点leaf没有子节点的节点。深度depth从根节点到某个节点的路径长度根节点深度通常为 0。高度height从该节点到最远叶子节点的最长路径上的边数。2.2 二叉树的存储结构通常采用链式存储每个节点包含数据域、左孩子指针、右孩子指针typedef struct TreeNode { int data; // 数据域 struct TreeNode *left; // 左孩子指针 struct TreeNode *right; // 右孩子指针 } TreeNode;2.3 创建二叉树节点TreeNode* createNode(int data)创建单个节点分配内存并初始化。TreeNode* createNode(int data) { TreeNode *node (TreeNode*)malloc(sizeof(TreeNode)); if (node NULL) { // 内存不足 printf(内存分配失败\n); exit(1); } node-data data; // 赋值数据 node-left node-right NULL; // 左右孩子初始为空 return node; }2.4 手动构建一棵示例二叉树为方便测试我们手动构建如下结构/* 1 / \ 2 3 / \ \ 4 5 6 */TreeNode* buildSampleTree() { TreeNode *root createNode(1); root-left createNode(2); root-right createNode(3); root-left-left createNode(4); root-left-right createNode(5); root-right-right createNode(6); return root; }2.5 二叉树的遍历方式遍历是指按照某种顺序访问树中的每一个节点。主要分为两大类深度优先遍历DFS沿着树的深度遍历分为先序、中序、后序。广度优先遍历BFS逐层遍历即层序遍历。2.5.1 先序遍历Pre-order顺序根 → 左子树 → 右子树对于示例树输出应为1 2 4 5 3 6void preOrder(TreeNode *root) { if (root NULL) return; // 递归出口空树 printf(%d , root-data); // 1. 访问根节点 preOrder(root-left); // 2. 递归遍历左子树 preOrder(root-right); // 3. 递归遍历右子树 }2.5.2 中序遍历In-order顺序左子树 → 根 → 右子树对于示例树输出应为4 2 5 1 3 6。若用于二叉搜索树中序遍历会得到有序序列。void inOrder(TreeNode *root) { if (root NULL) return; inOrder(root-left); // 1. 遍历左子树 printf(%d , root-data); // 2. 访问根节点 inOrder(root-right); // 3. 遍历右子树 }2.5.3 后序遍历Post-order顺序左子树 → 右子树 → 根对于示例树输出应为4 5 2 6 3 1。常用于释放树的内存先删子节点再删父节点。void postOrder(TreeNode *root) { if (root NULL) return; postOrder(root-left); // 1. 遍历左子树 postOrder(root-right); // 2. 遍历右子树 printf(%d , root-data); // 3. 访问根节点 }2.5.4 层序遍历Level-order—— BFS逐层从上到下、从左到右访问。对于示例树输出应为1 2 3 4 5 6。层序遍历需要借助队列来实现void levelOrder(TreeNode *root) { if (root NULL) return; // 使用链式队列此处需引入之前实现的 LinkQueue或直接用循环数组模拟 LinkQueue q; initLinkQueue(q); enLinkQueue(q, root); // 根节点入队 while (!isEmptyLink(amp;q)) { TreeNode *cur NULL; deLinkQueue(amp;q, amp;cur); // 出队一个节点 printf(%d , cur-gt;data); // 访问该节点 if (cur-gt;left) // 左孩子不空则入队 enLinkQueue(amp;q, cur-gt;left); if (cur-gt;right) // 右孩子不空则入队 enLinkQueue(amp;q, cur-gt;right); } printf(\n); }注意上述LinkQueue需要将数据类型改为TreeNode*。实际工程中通常使用独立的队列实现或使用 C STL 的queue。2.6 释放二叉树的内存必须使用后序遍历的方式释放确保先释放子节点再释放父节点否则会产生内存泄漏或野指针。void freeTree(TreeNode *root) { if (root NULL) return; freeTree(root-left); // 先释放左子树 freeTree(root-right); // 再释放右子树 free(root); // 最后释放根节点 }2.7 完整测试示例int main() { TreeNode *root buildSampleTree(); printf(先序遍历: ); preOrder(root); printf(\n); printf(中序遍历: ); inOrder(root); printf(\n); printf(后序遍历: ); postOrder(root); printf(\n); printf(层序遍历: ); levelOrder(root); freeTree(root); return 0; }总结二叉树是递归定义的完美体现。四种遍历方式覆盖了绝大多数应用场景先序可用于拷贝树中序可获得有序序列BST后序用于安全释放内存层序用于按层处理如图像渲染。掌握它们就掌握了树形结构的基础。

相关新闻

linux根文件系统是如何加载的

linux根文件系统是如何加载的

问题:内核在磁盘文件系统中,要加载内核,就必须先加载文件系统。但根文件系统又是被内核负责加载的,它是内核的启动参数,没有它,内核是无法启动的。到底先有鸡,还是先有蛋?机器是如何…

2026/10/19 21:33:32 阅读更多 →
Manus上下文工程:大模型能力释放的创新实践

Manus上下文工程:大模型能力释放的创新实践

1. Manus与上下文工程的创新结合Manus作为新一代AI工程平台,其核心突破在于将传统的大模型能力释放问题转化为可量化、可复制的上下文工程体系。这种思路转变直接解决了当前大模型应用中的三个关键痛点:响应不可控、知识碎片化和任务连贯性差。我在实际企…

2026/10/18 12:34:30 阅读更多 →
深度学习新手入门:从零搭建PyTorch环境到MNIST手写数字识别实战

深度学习新手入门:从零搭建PyTorch环境到MNIST手写数字识别实战

在实际项目中,很多开发者对深度学习抱有浓厚兴趣,但面对复杂的理论、庞大的框架和繁琐的环境配置,常常感到无从下手,最终停留在“Hello World”阶段。本文旨在为希望快速上手并完成第一个深度学习项目的初学者,提供一条…

2026/10/18 12:34:40 阅读更多 →

最新新闻

EfficientNetV2架构深度解析:tf_efficientnetv2_b3.in1k为何能又快又小?

EfficientNetV2架构深度解析:tf_efficientnetv2_b3.in1k为何能又快又小?

【免费下载链接】tf_efficientnetv2_b3.in1k 项目地址: https://ai.gitcode.com/hf_mirrors/timm/tf_efficientnetv2_b3.in1k 点击查看 免费下载 本文以开源预训练模型 tf_efficientnetv2_b3.in1k 为例,带你快速看懂这个图像分类模型:它仅用…

2026/10/20 2:01:14 阅读更多 →
GhostTrack:IP归属、号码归属与用户名注册速查——不用开浏览器

GhostTrack:IP归属、号码归属与用户名注册速查——不用开浏览器

GhostTrack:IP归属、号码归属与用户名注册速查——不用开浏览器 【免费下载链接】GhostTrack Useful tool to track location or mobile number 项目地址: https://gitcode.com/GitHub_Trending/gh/GhostTrack GhostTrack 是一个 Python 编写的 OSINT 脚本&a…

2026/10/20 2:01:14 阅读更多 →
Linux内核6.x学习路线:从环境搭建到调试进阶的专栏指南

Linux内核6.x学习路线:从环境搭建到调试进阶的专栏指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 2:01:14 阅读更多 →
树莓派与Arduino选型指南:打破裸机/系统二分法

树莓派与Arduino选型指南:打破裸机/系统二分法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 2:01:14 阅读更多 →
Linux显示驱动调试工具链:从DRM/KMS到PHY寄存器的全栈诊断

Linux显示驱动调试工具链:从DRM/KMS到PHY寄存器的全栈诊断

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 2:01:14 阅读更多 →
Unity代码热更新实战:ILRuntime集成Addressable的完整方案与避坑指南

Unity代码热更新实战:ILRuntime集成Addressable的完整方案与避坑指南

做Unity客户端这些年,只要是做手游的,基本绕不开热更新这个话题。资源热更还好说,AssetBundle或者Addressable都能解决,真正麻烦的是代码热更。以前用Lua,好是好,但团队要养Lua程序员,C#的代码也…

2026/10/20 2:00:13 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →