数据结构( 二叉树)
⚙️第一部分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/7/27 8:58:10 阅读更多 →
Manus上下文工程:大模型能力释放的创新实践

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

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

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

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

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

2026/7/27 8:58:10 阅读更多 →

最新新闻

OpenClaw开源AI框架:低代码开发与硬件需求解析

OpenClaw开源AI框架:低代码开发与硬件需求解析

1. 当AI开始“养虾”:OpenClaw的定位与争议最近在开发者圈子里,一个叫OpenClaw的开源项目突然火了。这个项目的名字很有意思——直译过来就是“开放式虾钳”,官方介绍它是一个“面向普通开发者的AI Agent开发框架”。但当我看到GitHub上那些复…

2026/7/27 9:13:15 阅读更多 →
2023机器学习五大前沿技术解析与应用实践

2023机器学习五大前沿技术解析与应用实践

1. 机器学习前沿技术全景概览 2023年无疑是机器学习领域又一个爆发式增长的年份。作为从业十余年的AI研究员,我有幸全程参与了这场年度技术盛会,并从中梳理出五大最具突破性的研究方向。不同于学术论文的艰深晦涩,本文将用工程师的视角&#…

2026/7/27 9:13:15 阅读更多 →
TI OMAP/DM/AM系列BGA回流焊工艺:从官方曲线到量产定制的实战指南

TI OMAP/DM/AM系列BGA回流焊工艺:从官方曲线到量产定制的实战指南

1. 项目概述与核心价值在电子制造业,尤其是涉及德州仪器(TI)OMAP、DM、AM系列这类高性能、高集成度处理器的产品组装中,回流焊工艺是决定最终产品可靠性的“临门一脚”。我处理过不少项目,从消费级手持设备到严苛的工业…

2026/7/27 9:13:15 阅读更多 →
AI分层协作:低成本模型与高级顾问的编程优化实践

AI分层协作:低成本模型与高级顾问的编程优化实践

1. 项目背景与核心问题 作为一名长期在AI编程领域摸爬滚打的开发者,我最近遇到了一个极具代表性的问题:低成本AI助手在复杂编码场景中的"卡壳"现象。具体表现为,当遇到需要深度推理的Bug时,这些模型能够识别出代码存在问…

2026/7/27 9:13:15 阅读更多 →
FS1.6到FS1.10代码移植实战指南

FS1.6到FS1.10代码移植实战指南

1. 项目背景与核心挑战FS1.6到FS1.10的代码移植是许多开发团队正在面临的实际工程问题。这两个版本之间存在架构调整、API变更和功能模块重组,直接拷贝代码往往会导致兼容性问题。根据实际项目经验,1.10版本在内存管理、线程调度和文件系统接口等方面进行…

2026/7/27 9:13:15 阅读更多 →
语音转文字(ASR)算法全景:从 GMM-HMM 到 Whisper/Conformer 的工程选型

语音转文字(ASR)算法全景:从 GMM-HMM 到 Whisper/Conformer 的工程选型

前言:重新定义人机交互的边界自动语音识别(Automatic Speech Recognition, ASR)技术历经七十余年的演进,已从实验室的玩具变为数十亿人每日使用的基础设施。从1952年贝尔实验室的Audrey系统只能识别数字0-9,到今天智能…

2026/7/27 9:12:15 阅读更多 →

日新闻

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →
SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

1. 项目概述:从寄存器手册到实战指南 如果你手头有一份类似德州仪器(TI)TMS320x240xA系列DSP的SPI模块技术手册,看着里面密密麻麻的寄存器位定义、时序图和公式,是不是感觉头大?这份资料虽然权威&#xff0…

2026/7/27 0:00:54 阅读更多 →
【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/27 6:31:56 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/27 4:01:12 阅读更多 →

月新闻