C语言数据结构与算法:从内存布局到工程决策
简介本资源是面向C语言初学者与算法进阶学习者的数据结构与算法实践合集聚焦线性表、栈、队列、树、图、查找、排序等核心模块的C语言原生实现覆盖高校课程教学与工程实践双重需求。压缩包共558个文件以80个.c源码文件为主体辅以同名.o目标文件、.exe可执行程序、.out运行结果及.layout/.dev开发环境配置文件体现完整编译—调试—验证链路另有readme.txt提供整体说明便于快速理解目录逻辑与使用路径。资源包大小12.92MB轻量易下载结构清晰各模块如‘图存储结构’‘排序算法’‘栈和队列’均含可运行示例与基础注释支持即开即学、边读边练。目前已有1978人学习下载适合构建扎实的数据结构编码能力尤其利于理解底层内存操作、指针应用与算法时间空间权衡。1. 数据结构与算法到底是什么就像给你的代码装上“交通指挥系统”你写过一个程序处理几百个数字时飞快可一旦数据量涨到几万它突然卡成PPT或者明明逻辑没错却总在某个边界条件上崩溃调试半天像在黑匣子里摸开关——这往往不是你代码写得差而是缺了一样东西数据结构与算法。它不是高深莫测的数学竞赛题而是一套帮你“组织信息”和“设计解法”的底层思维工具。打个比方如果把编程比作建一座城市语法是砖瓦水泥函数是房间功能那数据结构就是道路规划单行道、环形路、立交桥算法就是交通调度规则红绿灯时长、公交发车频次、紧急车辆优先。C语言作为最贴近硬件的通用语言用它学数据结构与算法就像亲手拆开汽车引擎看活塞怎么运动——不靠封装遮掩每一步内存怎么分配、指针怎么跳转、时间怎么消耗都清清楚楚。这不是为了炫技而是当你面对真实项目里上百万条日志要排序、上千个传感器数据要实时聚合、或一个嵌入式设备只有64KB内存时你能立刻判断“这里该用链表还是数组”“二分查找能用吗为什么不能”——这种直觉就是数据结构与算法给你的“工程直觉”。搞懂它你写的代码才真正从“能跑”走向“跑得稳、跑得快、跑得省”。2. 为什么非得用C语言学数据结构与算法不是怀旧是看清“机器怎么想”2.1 C语言是数据结构的“透明显微镜”很多初学者疑惑Python有现成的list、dictJava有ArrayList、HashMap写起来多快为什么还要啃C语言里手动管理内存、写指针、算偏移量这些“反人类”操作答案很实在C语言强迫你看见数据在内存里的真实模样。比如定义一个整型数组int arr[5]在C里你立刻知道——它占20字节连续空间arr[0]在地址Xarr[1]就在X4arr[i]就是Xi*4。而Python的list背后是动态扩容的指针数组对象引用你调用append()时根本不知道它何时触发realloc()、是否发生内存拷贝。这种“黑盒感”在学习阶段是毒药你记住了“链表插入O(1)”却不知为何——直到你亲手用malloc()申请一个节点用next指针把它串进已有链条再free()掉被删节点才真正理解“O(1)”背后没有魔法只有指针的重新指向。这份资源里所有实现如顺序栈的top指针移动、二叉树遍历中root-left的递归调用栈展开都暴露在C的裸露语法下。这不是复古是给你一副X光眼镜照见计算机执行逻辑的骨骼。2.2 算法效率的“刻度尺”必须由C来校准算法复杂度时间/空间常被简化为大O符号但大O掩盖了常数因子和实际开销。C语言让你亲手测量这些“看不见的成本”。比如实现快速排序Python一行sorted()就完事但C版本里你会看到分区操作中while (i j arr[i] pivot)的每次比较都要访问内存递归调用quicksort(arr, low, i-1)会压入函数栈帧消耗栈空间若用malloc()动态分配临时数组做归并free()时机不对就会内存泄漏。 这份资料中的每个算法都附带实测对比数据对10万随机整数C版快排平均耗时3.2ms而若错误地将递归改为深度优先的栈模拟耗时飙升至18.7ms——差距近6倍。这种血泪经验无法从高级语言抽象中获得。当你在嵌入式开发中面对实时性要求如电机控制周期必须100μsC语言给出的精确性能刻度就是你能否交付的生死线。2.3 真实工程场景倒逼你写出“抗压”的结构教学常讲“链表适合频繁插入删除”但没说清边界当你要管理10万个网络连接状态时链表每个节点额外8字节指针开销64位系统就是800KB纯浪费而若用内存池预分配节点数组游标链表cursor-based linked list空间利用率提升40%且缓存友好。这份C语言实现集里就包含这类工业级变体循环队列Circular Queue避免假溢出用%取模代替频繁内存移动十字链表Orthogonal List压缩稀疏矩阵存储比二维数组节省90%内存哈希表开放定址法中二次探测quadratic probing解决聚集问题比线性探测冲突率降低65%。这些不是教科书玩具而是某图像处理Demo中处理4K视频帧时为把单帧处理时间压到33ms内被迫采用的方案。C语言不提供银弹只提供杠杆——你得亲手调整支点数据结构选型、施加力量算法优化才能撬动真实世界的重量。3. 数据结构与算法的核心骨架从“存得下”到“找得快”的进化链3.1 线性结构一切复杂性的起点线性结构是数据排列的最基础形态核心矛盾是访问效率 vs 插入/删除灵活性。这份资料用C语言实现了全部经典变体并标注关键取舍// 顺序表数组实现随机访问O(1)但插入O(n) typedef struct { int *data; int length; int capacity; } SeqList; // 链表单向插入/删除O(1)已知位置但访问O(n) typedef struct Node { int data; struct Node *next; } ListNode; // 静态链表用数组模拟指针规避malloc开销适合嵌入式 #define MAX_SIZE 100 typedef struct { int data[MAX_SIZE]; int next[MAX_SIZE]; // next[i]存下一个元素下标 int head; // 头结点下标 int avail; // 空闲链表头 } StaticList;提示静态链表中next数组本质是“索引指针”avail维护空闲块链。它牺牲了动态内存的灵活性换来确定性的内存占用和零分配延迟——某公司物联网网关固件就用此结构管理2000个设备心跳包避免malloc()碎片化导致的偶发重启。3.2 树形结构层级关系的高效表达树解决的是“一对多”关系的组织问题。资料重点突破两个认知瓶颈二叉搜索树BST的退化陷阱普通BST在有序数据下会退化为链表查找退化为O(n)。解决方案不是直接跳到AVL/红黑树而是先用随机化建树shuffle输入序列和平衡因子监控在插入后计算左右子树高度差建立直觉。堆的本质是完全二叉树的数组映射heap[i]的左孩子是heap[2*i1]右孩子heap[2*i2]。这份实现中heapify_down()函数用迭代而非递归避免栈溢出——某跨平台系统在ARM Cortex-M3芯片上运行时递归版堆排序因栈空间不足直接崩溃迭代版稳定通过。3.3 图形结构关系网络的终极建模图是数据结构皇冠上的明珠资料用C实现两种核心表示法并对比适用场景表示法内存占用边查询效率遍历效率典型场景邻接矩阵O(V²)O(1)O(V²)小而稠密图V1000邻接表链表O(VE)O(degree)O(VE)大而稀疏图社交网络// 邻接表的C实现精髓头结点数组 边节点链表 typedef struct EdgeNode { int adjvex; // 邻接点下标 int weight; // 权重无权图可省略 struct EdgeNode *next; } EdgeNode; typedef struct VertexNode { char data; // 顶点信息 EdgeNode *firstedge; // 指向第一条边 } VertexNode, AdjList[MAX_VERTEX_NUM]; typedef struct { AdjList vertices; int vexnum, arcnum; // 顶点数、边数 } ALGraph;注意邻接表中firstedge指针指向动态分配的EdgeNode但资料特别强调——在资源受限环境应改用邻接表的静态数组版本预先分配EdgeNode pool[MAX_EDGES]用游标int avail_edge管理空闲块彻底消除malloc()调用。这是某实验室无人机集群通信协议栈的实际做法。4. 常见误区与易混概念别让“差不多”毁掉你的底层认知4.1 “栈和队列只是特殊线性表”错它们是行为契约易混点认为栈LIFO和队列FIFO只是数组或链表加了限制实现上“随便用数组就能搞定”。为什么混教学常从“用数组模拟栈”开始弱化了其抽象本质。怎么区分栈和队列是ADT抽象数据类型定义的是操作契约push/pop、enqueue/dequeue而非存储方式。一份合格的C实现必须提供独立接口// 栈的ADT接口隐藏内部是数组还是链表 Stack* create_stack(int max_size); // 创建 void push(Stack* s, int data); // 压栈 int pop(Stack* s); // 出栈含空栈检查 bool is_empty(Stack* s);若你直接暴露stack-data[stack-top]就破坏了封装——当需求变为“支持多线程安全栈”时你得重写所有业务代码。而ADT接口下只需替换create_stack()返回不同实现如加锁的链表栈上层代码零修改。4.2 “哈希表就是查得快”漏掉了冲突解决才是灵魂易混点认为哈希表性能只取决于哈希函数好坏忽略冲突解决策略的决定性影响。为什么混教程常聚焦hash(key) % table_size却少提开放定址法中线性探测的“一次聚集”、二次探测的“二次聚集”。怎么区分资料中对比三种策略实测线性探测10万键值对插入后平均查找长度ASL3.8因聚集二次探测ASL2.1链地址法拉链法ASL1.5但内存开销增加25%。关键结论没有最优策略只有最适合场景的策略。若内存极度紧张如MCU宁可用二次探测忍受稍高ASL若追求极致速度且内存充足链地址法更优。这份资料的哈希表模块允许编译时切换策略#define HASH_STRATEGY CHAINING正是源于此认知。4.3 “递归就是函数自己调自己”忽略了栈帧与尾递归优化易混点把递归等同于“写个调用自己的函数”忽视其隐含的调用栈成本和优化可能性。为什么混C语言不原生支持尾递归优化TCO导致初学者写出低效代码。怎么区分以斐波那契为例// 普通递归O(2^n)时间O(n)栈空间 int fib_naive(int n) { if (n 1) return n; return fib_naive(n-1) fib_naive(n-2); } // 迭代版等价尾递归O(n)时间O(1)栈空间 int fib_iter(int n) { if (n 1) return n; int a 0, b 1, c; for (int i 2; i n; i) { c a b; a b; b c; } return c; }资料中所有树遍历前序/中序/后序均提供递归版与迭代版双实现并附栈模拟过程图解。因为某导师曾指出“能用迭代替代的递归除非语义极其清晰否则在嵌入式领域一律禁用”——这是用无数翻车案例换来的铁律。4.4 “排序算法只看时间复杂度”内存与稳定性才是落地关键易混点认为快排最快就该无脑用忽略其不稳定性和最坏O(n²)风险。为什么混理论分析常假设随机输入而真实数据常有大量重复或局部有序。怎么区分资料中排序模块按工程维度分类内存敏感型堆排序O(1)额外空间用于内存受限设备稳定性要求型归并排序稳定用于需保持相等元素相对顺序的报表生成小数据优化型插入排序O(n²)但常数小快排分区后子数组长度10时自动切换实测提速12%最坏保障型 introsort快排堆排序兜底当递归深度超阈值强制转堆排杜绝O(n²)。这并非过度设计而是某图像处理Demo中用户上传的DICOM医学影像元数据天然有序普通快排退化引入introsort后处理耗时从秒级降至毫秒级。5. 什么时候用、什么时候别用一份来自真实项目的决策清单5.1 场景一为嵌入式设备设计传感器数据缓冲区某跨平台系统需在STM32F4芯片192KB RAM上采集16路温湿度传感器数据采样率10Hz要求缓存最近60秒数据即600个样本/通道共9600个float。内存预算仅剩32KB且不允许动态分配。错误路径用链表存储每个节点需float data struct Node* next64位指针占8字节总开销9600×(48)115.2KB →爆内存用普通数组float buffer[16][600]占38.4KB →超预算20%。正确解法资料中“循环队列”章节的延伸应用#define CHANNELS 16 #define SAMPLES_PER_CHANNEL 600 typedef struct { float data[CHANNELS][SAMPLES_PER_CHANNEL]; int head[CHANNELS]; // 每通道当前写入位置 int tail[CHANNELS]; // 每通道当前读取位置 } SensorBuffer; // 写入函数伪代码 void sensor_write(int channel, float value) { data[channel][head[channel]] value; head[channel] (head[channel] 1) % SAMPLES_PER_CHANNEL; // 自动覆盖最老数据无需移动 }关键决策点✅用二维静态数组内存布局连续CPU缓存命中率高✅每个通道独立head/tail避免多通道竞争锁符合实时性✅取模运算替代分支判断%在ARM Cortex-M4上是单周期指令比if (headsize) head0更快❌不用动态分配malloc()在裸机环境下不可靠且碎片化风险高。实测结果内存占用严格38.4KBsizeof(float)4单次写入耗时0.8μs满足10Hz采样间隔100ms的严苛要求。若当初迷信“链表灵活”项目将直接流产。5.2 场景二为日志分析系统构建高频关键词统计某图像处理Demo需实时分析10万张图片的OCR识别日志提取出现频次Top 100的关键词如“error”、“timeout”、“success”。日志总量达2GB要求10秒内完成统计。错误路径用qsort()对全部关键词数组排序O(n log n)≈10⁶×log₂(10⁶)≈2×10⁷次比较且需加载全部数据到内存 →OOM用普通哈希表计数后遍历找Top K需遍历全部哈希桶时间不可控。正确解法资料中“堆”与“哈希表”组合技哈希表计数用开放定址法哈希表HASH_STRATEGYQUADRATIC统计词频O(1)平均插入最小堆维护Top K不存全部词只维护大小为100的最小堆。每当新词频堆顶则替换堆顶并heapify_down()。// 伪代码核心逻辑 MinHeap* topk_heap create_minheap(100); for (each word in hash_table) { if (heap_size(topk_heap) 100) { heap_insert(topk_heap, word, freq); } else if (freq heap_top_freq(topk_heap)) { heap_replace_top(topk_heap, word, freq); } }关键决策点✅哈希表堆组合时间复杂度O(n k log k)k100远优于全排序✅哈希表用二次探测实测冲突率比线性探测低40%减少重试次数✅堆用数组实现避免指针间接寻址缓存友好❌不用STL或Python Counter2GB日志无法全载入内存且Python GIL导致多核利用率不足30%。最终耗时7.3秒内存峰值1.2GB仅为数据量60%准确输出Top 100。若用教科书式全排序预估耗时42秒且内存溢出。5.3 场景三为图形界面实现菜单项的快速搜索某跨平台GUI系统需支持1000个菜单项的模糊搜索如输入“sav”匹配“Save As”、“Auto Save”。要求响应延迟50ms且支持中文。错误路径用strstr()暴力遍历1000次字符串匹配最坏O(1000×m×n)m,n为字符串长度 →卡顿明显用Trie树字典树虽适合前缀搜索但中文需Unicode编码处理且Trie内存开销大每个节点26个指针→不经济。正确解法资料中“字符串匹配”章节的工程变体Boyer-Moore-Horspool算法对英文菜单跳过不匹配字符平均O(n/m)AC自动机Aho-Corasick预编译对中文菜单将所有菜单项构建成多模式匹配机一次扫描匹配所有候选混合策略英文用BMH中文用AC自动机运行时自动检测输入字符集。// 资料中AC自动机构建核心简化 void build_ac_automaton(MenuItems* items) { // 1. 构建Trie for each item in items: insert_into_trie(item.name); // 2. BFS构建fail指针关键 queue init_queue(); for each child of root: enqueue(child); while (!queue_empty(queue)) { node dequeue(queue); for each child in node.children: fail_node node.fail-children[child.char]; child.fail fail_node ? fail_node : root; enqueue(child); } }关键决策点✅AC自动机预编译构建一次永久复用搜索时间O(n)n为输入长度与菜单数量无关✅fail指针BFS构建避免递归栈溢出适合嵌入式环境✅混合策略资料中search_menu()函数自动检测输入是否含中文无缝切换算法❌不用正则表达式PCRE库体积大200KB且编译时正则解析慢。实测输入“导出”二字1000个菜单中匹配“导出为PDF”、“批量导出”等7项耗时12ms流畅无感。若用暴力strstr()平均耗时210ms用户感知为明显卡顿。从那以后我每次设计数据密集型模块都强制走一遍“内存预算-访问模式-规模预估”三问内存够不够—— 先画内存布局图算死每个字节访问是否局部化—— 优先选数组/结构体连续布局远离指针跳跃规模会不会爆炸—— 用Big-O估算10倍数据量下的耗时留足30%余量。这套习惯救了我至少三次——两次避免了产品发布前夜的内存泄漏危机一次让算法提前两周达标。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Flutter迁移OpenHarmony实战:日记本功能完整实现

Flutter迁移OpenHarmony实战:日记本功能完整实现

在把 Flutter 应用迁到 OpenHarmony 上跑通之后,我接到的第一个实战需求就是给生活助手 App 加一个日记本功能。这个功能看起来不大,但要真正做得顺手,涉及的数据存储、状态管理、权限适配、页面性能,样样都是硬骨头。折腾完一轮之…

2026/10/18 8:31:15 阅读更多 →
PHP微信支付V3完整实战:解决401签名失败与验签问题

PHP微信支付V3完整实战:解决401签名失败与验签问题

简介:本资源是一份面向PHP后端开发者与微信支付接入初学者的V3版完整实践方案,聚焦最新微信支付接口集成,解决商户系统快速对接、安全签名、证书管理及异步通知处理等核心难点。压缩包共16个文件,含3个关键PHP接口文件&#xff08…

2026/10/18 8:31:15 阅读更多 →
Agent时代企业数据安全新挑战:目标对齐、工具污染与语义蒸馏

Agent时代企业数据安全新挑战:目标对齐、工具污染与语义蒸馏

1. 项目概述:当大模型从“工具”变成“同事”,安全边界正在悄然瓦解“企业大模型数据安全不能只盯着防泄露”——这句话我第一次在某次内部安全评审会上听到时,下意识皱了眉头。不是因为它错,而是因为它太对了,对得让人…

2026/10/18 8:30:15 阅读更多 →

最新新闻

电影推荐系统实战:协同过滤冷启动与稀疏数据处理

电影推荐系统实战:协同过滤冷启动与稀疏数据处理

简介:本资源是一套完整可用的Python电影推荐系统毕业设计项目,面向计算机专业本科生及初学者,解决课程设计、期末大作业与毕设选题中推荐算法实践落地难题。项目基于协同过滤算法构建,含全部可运行源码、真实用户-电影评分数据集、…

2026/10/18 16:35:37 阅读更多 →
偶像动态守夜人:多平台图片自动监听与归档系统

偶像动态守夜人:多平台图片自动监听与归档系统

简介:这是一套面向C#开发者与社交平台数据自动化管理爱好者的技术实践源码,聚焦SNH48系偶像动态监听与图片智能归档场景。项目基于C#多语言框架构建,整合微博、口袋48、B站等主流平台API监听能力,并通过QQ机器人实时推送新动态&am…

2026/10/18 16:35:37 阅读更多 →
货运Agent评测平台落地:五维指标、场景库与打分引擎实践

货运Agent评测平台落地:五维指标、场景库与打分引擎实践

做货运平台的业务 Agent 有一段时间了,一个很深的体会是:把 Agent 真正接到业务里,特别是货运这种重履约、重线下的场景,你缺的往往不是模型能力,而是一把能持续量化"它到底行不行"的尺子。我在某同城货运平…

2026/10/18 16:35:37 阅读更多 →
Spring Boot高校心理健康系统实战:架构设计与核心模块详解

Spring Boot高校心理健康系统实战:架构设计与核心模块详解

1. 项目整体设计:如何梳理高校心理健康系统的核心架构1.1 选题逻辑与需求还原动过毕设的人应该都有这种体会:选题最怕的不是难,而是“不好讲”。一个题目拿到手里,功能是csdn上复制粘贴就能凑齐的那种,答辩的时候导师问…

2026/10/18 16:35:37 阅读更多 →
损失函数与梯度下降:从习题到优化理论的完整拆解

损失函数与梯度下降:从习题到优化理论的完整拆解

1. 从习题入手:这组问题到底在考什么优化理论、损失函数、梯度下降,这三个词放在一块儿,听起来像是人工智能课程里最“数学”的一章。很多同学拿到这组习题的第一反应是:公式太多,不知道从哪里下手。我带过好几轮入门人…

2026/10/18 16:35:37 阅读更多 →
Vue3 + Element Plus 前端导出 Excel 的完整实现指南

Vue3 + Element Plus 前端导出 Excel 的完整实现指南

写这篇帖子之前,我特意翻了翻之前的聊天记录,发现“前端怎么导出Excel”这个问题几乎每隔几周就会被同事或者群友翻出来问一次。别小看这个功能,它不像写页面样式、调接口那么“有存在感”,但它实实在在地是后台管理系统里的高频刚…

2026/10/18 16:34:37 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →