树与森林遍历全解析:从二叉树到随机森林的算法核心
1. 项目概述从“树”到“森林”的遍历全景图在数据结构和算法的世界里“遍历”是一个基础得不能再基础却又至关重要的操作。它就像我们探索一个未知城市的地图遍历就是那条带你走遍每一条街道、拜访每一个地标的路线。今天我们不聊简单的线性结构而是聚焦于那些更具层次感和复杂性的非线性结构——树以及由多棵树构成的森林。无论是你正在学习的《数据结构》课程还是在准备面试刷LeetCode亦或是在实际项目中处理如文件系统、DOM树、决策模型等场景对树和森林遍历的深刻理解都是你绕不开的核心技能。很多人觉得遍历无非就是前序、中序、后序那几种背下来就行。但真正在解决“根据中序和后序重建二叉树”、“序列化和反序列化一颗N叉树”、“对多棵决策树组成的随机森林进行预测”这类问题时你会发现仅仅知道遍历顺序是远远不够的。你需要理解每种遍历的“访问时机”所代表的语义需要掌握递归与非递归迭代两种思维模式的切换更需要明白在森林这种复合结构下遍历策略如何灵活组合。这篇文章我将结合十多年的开发和教学经验为你彻底拆解树与森林的遍历不止于概念更深入到代码实现、应用场景以及那些容易踩坑的细节让你真正拥有“透视”非线性结构的能力。2. 核心概念与遍历的“道”与“术”在深入具体遍历方法之前我们必须先统一“语言”理解几个核心概念这是所有后续讨论的基石。树是一种递归定义的数据结构由n个节点组成有且仅有一个根节点其余节点可分为m个互不相交的有限集合每个集合本身又是一棵树称为子树。森林就是m棵互不相交的树的集合。你可以把森林看作一棵树去掉根节点后的样子。遍历的本质是按照某种规则访问树中的每个节点且仅访问一次。这里的“访问”是一个抽象操作具体可能是打印节点值、修改节点状态、收集节点信息等。遍历的“道”在于理解递归思想——将一棵复杂的树分解为“根节点”、“左子树”、“右子树”对二叉树而言或“根节点”和“子树集合”对一般树而言这几个更小的部分来处理。而遍历的“术”则体现在我们安排“访问根节点”这个操作与“遍历各子树”这两个动作的相对顺序上。2.1 二叉树的三种经典遍历二叉树是最简单、最典型的树结构其遍历是理解所有树遍历的基础。三种经典遍历的定义完全由“访问根节点”的时机决定。2.1.1 前序遍历顺序根节点 - 左子树 - 右子树。 语义先处理当前节点再处理它的后代。这非常符合“深度优先”探索中“先记录再深入”的直觉。在复制一棵树、序列化、或需要先知道父节点信息才能处理子节点的场景如计算目录大小中非常有用。 递归实现一目了然def preorder_traversal(root): if root is None: return visit(root) # 访问根节点 preorder_traversal(root.left) # 遍历左子树 preorder_traversal(root.right) # 遍历右子树2.1.2 中序遍历顺序左子树 - 根节点 - 右子树。 语义对于二叉搜索树中序遍历会得到一个升序序列。这是它的王牌特性。它体现了“先处理完左边的所有再处理中间最后处理右边”的一种有序过程。常用于BST的排序输出、表达式树求值中缀表达式等。 递归实现def inorder_traversal(root): if root is None: return inorder_traversal(root.left) # 遍历左子树 visit(root) # 访问根节点 inorder_traversal(root.right) # 遍历右子树2.1.3 后序遍历顺序左子树 - 右子树 - 根节点。 语义先处理所有子节点最后处理父节点。这符合“先解决子问题再解决父问题”的后续依赖逻辑。在释放一棵树的内存、计算目录总大小需要先知道子目录大小、后序表达式求值等场景中不可或缺。 递归实现def postorder_traversal(root): if root is None: return postorder_traversal(root.left) # 遍历左子树 postorder_traversal(root.right) # 遍历右子树 visit(root) # 访问根节点注意这里的“左”、“右”顺序是约定俗成的。对于某些特定结构的树如表达式树顺序是固定的。但在一般树或森林中“子树”之间可能没有左右之分只有集合关系此时“前序”和“后序”依然有意义但“中序”通常不再适用。2.2 层序遍历广度优先的策略与前三种“深度优先”的遍历不同层序遍历属于“广度优先”。它按树的层级从上到下、从左到右通常约定访问节点。这需要借助队列来实现。 算法步骤将根节点入队。当队列不为空时循环 a. 出队一个节点并访问。 b. 将该节点的所有子节点对于二叉树是左、右孩子依次入队。 层序遍历能直观地展示树的形状常用于寻找最短路径如二叉树的最小深度、按层打印节点等。from collections import deque def level_order_traversal(root): if not root: return queue deque([root]) while queue: node queue.popleft() visit(node) if node.left: queue.append(node.left) if node.right: queue.append(node.right)3. 从二叉树到一般树与森林的遍历扩展理解了二叉树的遍历我们就可以将概念推广到更一般的树每个节点可以有任意多个孩子和森林。3.1 一般树的遍历对于一般树由于一个节点可能有多个孩子没有明确的“左”“右”之分因此“中序遍历”没有定义。但前序和后序遍历依然清晰。前序遍历先访问根节点然后依次对每个子树进行前序遍历。后序遍历先依次对每个子树进行后序遍历最后访问根节点。 实现上通常使用一个孩子节点列表如children来存储所有子节点然后用循环遍历这个列表。class GeneralTreeNode: def __init__(self, val): self.val val self.children [] def preorder_general(root): if not root: return visit(root) for child in root.children: preorder_general(child) def postorder_general(root): if not root: return for child in root.children: postorder_general(child) visit(root)3.2 森林的遍历森林是多棵树的集合。遍历森林本质上就是依次遍历其中的每一棵树。但这里有一个精妙的联系和两种主流的定义方式常常是理解和应用的难点。3.2.1 森林的两种遍历定义先根遍历森林的前序遍历若森林非空则访问第一棵树的根节点。先根遍历第一棵树的根节点的子树森林。先根遍历除去第一棵树后剩余的树构成的森林。简单说就是依次对森林中的每棵树进行前序遍历。这是最直观、最常用的方式。后根遍历森林的后序遍历若森林非空则后根遍历第一棵树的根节点的子树森林。访问第一棵树的根节点。后根遍历除去第一棵树后剩余的树构成的森林。简单说就是依次对森林中的每棵树进行后序遍历。3.2.2 森林与二叉树的对应关系重点这是数据结构中一个非常经典且实用的知识点任何森林都可以唯一地对应一棵二叉树通过“孩子兄弟表示法”并且森林的先根遍历和后根遍历分别对应这棵二叉树的先序遍历和中序遍历。孩子兄弟表示法每个节点设置两个指针一个指向其第一个孩子FirstChild一个指向其下一个兄弟NextSibling。这样任意复杂的树或森林都能用二叉树的结构来存储。遍历对应关系森林的先根遍历 其对应二叉树的前序遍历。森林的后根遍历 其对应二叉树的中序遍历。 这个关系非常重要因为它意味着我们可以利用成熟的二叉树遍历算法包括递归和非递归来处理森林极大地简化了问题和实现。实操心得当你在处理一个类似森林的结构比如一个多级评论列表、一个组织架构图时如果感到直接操作复杂不妨在脑子里或代码里先将其转换成“孩子兄弟表示法”的二叉树。然后你想对森林做“先根遍历”例如扁平化输出所有评论就相当于对那棵二叉树做前序遍历。这个思维转换能帮你快速借用二叉树的大量现成工具和算法。4. 遍历的代码实现递归与迭代的深度解析知道概念只是第一步能写出健壮、高效的代码才是硬道理。遍历的实现主要有递归和迭代两种范式各有优劣。4.1 递归实现简洁与系统开销上面的示例代码基本都是递归实现。递归的优点是代码极其简洁几乎直接对应数学定义易于理解和编写。但其缺点也明显递归深度受系统栈空间限制对于深度很大的树如退化成链表的二叉树可能导致栈溢出。此外函数调用的开销也比迭代略大。4.2 迭代实现手动模拟栈与队列迭代实现通过手动维护栈或队列来模拟递归过程避免了系统栈溢出的风险是工程中更稳健的选择也是面试常考点。4.2.1 二叉树前序遍历的迭代实现核心思路利用栈我们模拟“访问根然后右孩子入栈左孩子入栈”的顺序。因为栈是后进先出所以要先让右孩子入栈。def preorder_iterative(root): if not root: return [] stack, result [root], [] while stack: node stack.pop() result.append(node.val) # 访问 # 先右后左保证出栈时是左先右后 if node.right: stack.append(node.right) if node.left: stack.append(node.left) return result4.2.2 二叉树中序遍历的迭代实现这是最需要技巧的一种。思路是使用一个指针curr和一个栈。curr负责一路向左深入栈负责保存沿途的“根”节点。def inorder_iterative(root): stack, result, curr [], [], root while curr or stack: # 一路向左把节点压入栈 while curr: stack.append(curr) curr curr.left # 弹出栈顶节点访问 curr stack.pop() result.append(curr.val) # 访问 # 转向右子树 curr curr.right return result4.2.3 二叉树后序遍历的迭代实现后序遍历的迭代有多种写法一种巧妙的方法是采用“根-右-左”的顺序遍历然后将结果反转即得到“左-右-根”。这利用了前序遍历迭代版的变体。def postorder_iterative(root): if not root: return [] stack, result [root], [] while stack: node stack.pop() result.append(node.val) # 注意这里先左后右因为最后要反转 if node.left: stack.append(node.left) if node.right: stack.append(node.right) return result[::-1] # 反转结果另一种更符合后序逻辑的方法是使用一个prev变量记录上一个访问的节点来判断当前节点的右子树是否已被访问。代码稍复杂但逻辑更直接。4.2.4 层序遍历的迭代实现如前所述使用队列。这里再给一个按层分组输出的版本这在面试中也很常见。def level_order_with_levels(root): if not root: return [] from collections import deque queue deque([root]) result [] while queue: level_size len(queue) current_level [] for _ in range(level_size): node queue.popleft() current_level.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) result.append(current_level) return result # 结果是二维数组每一层一个子数组5. 遍历的核心应用场景与实战剖析遍历不是枯燥的理论它在无数场景中发挥着关键作用。理解应用场景才能明白为何要如此设计遍历。5.1 在基础数据结构操作中的应用二叉搜索树的排序与查找BST的中序遍历即升序序列。这是BST的核心特性之一用于范围查询、排序输出等。表达式树的求值前序遍历对应前缀表达式波兰式。中序遍历需加括号对应中缀表达式。后序遍历对应后缀表达式逆波兰式。计算机计算表达式时常将中缀表达式转为后缀表达式然后利用栈进行后序遍历求值非常高效。堆的构建与调整虽然堆通常用数组存储但其逻辑是一棵完全二叉树。堆化过程可以看作一种特殊的层序或后序遍历调整。5.2 在算法问题中的经典应用树的序列化与反序列化将树结构转化为字符串或字节流以便存储或传输再反向构建回树。通常使用前序或层序遍历来实现。前序遍历序列化时需要记录空节点如用“#”以唯一确定树的结构。# 前序遍历序列化 def serialize(root): def dfs(node): if not node: vals.append(#) return vals.append(str(node.val)) dfs(node.left) dfs(node.right) vals [] dfs(root) return ,.join(vals)重建二叉树经典面试题。给定前序和中序序列或中序和后序序列可以唯一确定一棵二叉树。核心思路是利用前序/后序确定根节点在中序中定位根节点以分割左右子树然后递归构建。寻找最近公共祖先在二叉树中寻找两个节点的最近公共祖先。可以通过后序遍历从底向上返回节点信息来实现。路径总和问题判断是否存在从根到叶子的路径其节点值之和等于目标值。通常使用前序遍历深度优先并沿途记录路径和。5.3 在复杂系统与模型中的应用文件系统遍历文件目录树是一棵典型的树。ls -R命令是前序遍历find命令可以指定多种遍历策略。计算文件夹总大小需要后序遍历先算子文件夹再加总。DOM树操作网页的DOM是一棵树。JavaScript的document.getElementById,getElementsByTagName等API底层都涉及树的遍历。前端框架的虚拟DOM Diff算法也深度依赖于树的遍历策略。决策树与随机森林这是“森林”概念的绝佳现实映射。随机森林由多棵决策树构成。单棵决策树的预测对一个样本进行预测时从根节点开始根据特征值选择分支相当于执行一次从根到叶的单一路径遍历。随机森林的预测森林的预测是“遍历”其中每一棵决策树对每棵树进行单一路径遍历然后集成所有树的结果如投票或平均。这里的“遍历森林”就是依次处理每一棵树。语法分析编译原理中语法分析生成的抽象语法树其遍历用于语义分析、代码生成等。游戏场景图与UI组件树游戏引擎中的场景管理和GUI框架中的组件管理也常采用树结构遍历用于渲染、事件传递等。6. 常见问题、易错点与性能优化在实际编码和面试中围绕遍历有无数“坑”。下面我总结了一些最常见的问题和优化技巧。6.1 理解误区与易错点混淆遍历顺序这是新手最容易犯的错尤其是中序和后序。务必记住是以“访问根节点”的时机来命名的。画一棵简单的三层二叉树手动模拟一遍流程比死记硬背有效得多。递归终止条件遗漏递归函数中if root is None: return这一句至关重要它处理了空子树的情况是递归能够正确返回的保证。忘记写会导致无限递归或访问空指针。迭代实现中的栈/队列操作顺序如前序遍历迭代中入栈顺序必须是先右后左层序遍历中队列出队后要将其孩子按从左到右的顺序入队。顺序错了结果就全错了。对“访问”操作的理解僵化“访问”不一定只是打印。它可能是将节点值加入列表、修改节点属性、进行某种计算等。要根据问题目标来定义visit函数。处理一般树时忘记循环所有孩子在写一般树的前序/后序遍历递归时一定要用for child in node.children遍历所有子节点而不是只处理第一个。6.2 性能考量与优化策略递归深度限制这是递归最大的隐患。Python默认递归深度约1000。对于可能很深的树如线性链表状的二叉树必须使用迭代法。在递归解法中如果问题规模明确很大可以尝试使用sys.setrecursionlimit提高限制但这并非根本解决之道。空间复杂度递归的空间复杂度取决于递归深度最坏情况斜树为O(n)。迭代法中栈/队列在最坏情况下也可能存储O(n)个节点如层序遍历存储最后一层。对于莫里斯遍历它能在O(1)额外空间不考虑结果存储的情况下完成中序遍历通过修改树的临时指针来避免使用栈。这是面试中的高阶考点但会破坏树的结构通常最后会恢复。时间复杂度所有遍历方式每个节点都被访问一次且仅一次时间复杂度都是O(n)其中n为节点数。这是遍历操作的下限。在遍历中修改结构这是一个危险操作。如果在遍历树的同时增加或删除节点可能会使迭代器失效或递归逻辑混乱。如果必须修改一个安全的模式是先遍历收集需要修改的节点信息然后再进行另一轮操作或者使用后序遍历在处理好子节点后再修改当前节点。6.3 调试与验证技巧可视化小树对于任何遍历算法用纸笔画一棵只有3-5个节点的小树手动模拟算法步骤是最有效的调试和理解方式。编写单元测试针对不同的树结构空树、单节点树、只有左子树、完全二叉树、普通树测试你的遍历函数确保边界条件正确。利用已知性质验证对BST进行中序遍历结果必须是升序。一棵树的节点数等于前序遍历结果数组的长度考虑空节点标记。层序遍历的结果结合每层节点数可以验证树的形状。遍历是打开树形结构所有奥秘的钥匙。从基础的递归定义到稳健的迭代实现再到与森林概念的融会贯通最后落地到各种生动的应用场景我希望这篇文章能帮你构建起一个关于树与森林遍历的完整知识图谱。理解不同遍历的语义比记住代码更重要掌握递归与迭代的转换能让你在编码时游刃有余而将遍历与实际问题如序列化、LCA、随机森林预测联系起来则是你知识价值的最终体现。下次当你面对一棵“树”时无论是代码里的数据结构还是现实中的问题模型希望你能清晰地知道该用哪种“走法”去探索它的每一个角落。

相关新闻

零成本构建企业级知识中枢指南:CTO 亲测有效的省钱方案

零成本构建企业级知识中枢指南:CTO 亲测有效的省钱方案

零成本构建企业级知识中枢指南:CTO 亲测有效的省钱方案 很多企业的知识管理现状可以用四个字概括:一团乱麻。 技术文档在 Git 里,合同在 NAS 上,会议纪要在钉钉里,设计方案在飞书里。想找一份三个月前的技术方案&#…

2026/10/14 23:51:51 阅读更多 →
Origin2021安装全攻略:从系统环境配置到疑难杂症解决

Origin2021安装全攻略:从系统环境配置到疑难杂症解决

1. 项目概述:当安装Origin2021成为一场“技术修行”如果你是一名理工科的研究生、实验室的科研人员,或者任何需要处理和分析实验数据的朋友,那么“Origin”这个名字对你来说一定不陌生。它几乎是科研绘图和数据分析领域的“瑞士军刀”&#x…

2026/10/14 23:51:24 阅读更多 →
雷鸟V4 AI智能眼镜技术解析:38g超轻设计与1:1大底显示体验

雷鸟V4 AI智能眼镜技术解析:38g超轻设计与1:1大底显示体验

雷鸟 V4 AI智能眼镜深度测评:38g超轻1:1大底,这才是第一视角的终极形态? 作为一名长期关注智能穿戴设备的技术博主,最近终于拿到了备受关注的雷鸟V4 AI智能眼镜。在实际体验两周后,我决定从技术角度为大家带来这份深度…

2026/10/13 9:58:14 阅读更多 →

最新新闻

Sub-Agents、Skills与知识库:大模型应用架构重构实践

Sub-Agents、Skills与知识库:大模型应用架构重构实践

去年做一个复杂业务场景的大模型应用时,我一开始图省事,把所有能力塞进单个 Agent:检索、生成、校验、执行全在一个上下文里跑。结果很快发现这条路走不通——prompt 越来越长,模型在工具调用里频繁迷失,多轮对话后甚至…

2026/10/14 23:51:18 阅读更多 →
智能体角色拆分实践:Sub-Agents、技能包与知识库协同跑通

智能体角色拆分实践:Sub-Agents、技能包与知识库协同跑通

1. 为什么要把智能体拆成角色,而不是做一个万能大脑做AI智能体项目,组里最常听到的一句话就是“能不能让这个Agent自己搞定所有事”。最开始谁都这么想,真做两个星期就会发现,任务越复杂,单个Agent越容易顾此失彼。这个…

2026/10/14 23:51:18 阅读更多 →
归并排序实战指南:从寻找大富翁读懂排序算法的取舍与细节

归并排序实战指南:从寻找大富翁读懂排序算法的取舍与细节

做这套题时我最初的提交记录特别丢人——先写了个裸的sort直接交,数据量不大,过了,但我自己清楚,这种写法对“寻找大富翁”可以说毫无解释力。题目考的是排序,可你要真只会调库,那“归并排序”四个字就永远…

2026/10/14 23:51:18 阅读更多 →
ScanNet SensReader:.sens RGB-D 传感器流文件格式与读取工具完全解析

ScanNet SensReader:.sens RGB-D 传感器流文件格式与读取工具完全解析

数据集计算机视觉3D视觉 【免费下载链接】ScanNet 项目地址&#xff1a; https://gitcode.com/gh_mirrors/sc/ScanNet 点击查看 免费下载 在 ScanNet 数据集中&#xff0c;每个扫描序列目录&#xff08;scene%04d_%02d&#xff09;都包含一个 <scanId>.sens 文件&#x…

2026/10/14 23:51:18 阅读更多 →
统一内存撑起万亿参数模型:本地部署大模型的算力与功耗实战指南

统一内存撑起万亿参数模型:本地部署大模型的算力与功耗实战指南

去年年底&#xff0c;我把一台以前只在数据中心见过的计算设备搬进了工位旁边的小机房里。开机那一刻&#xff0c;我盯着监控面板半天没说话——系统里那串 748GB 统一内存余量&#xff0c;比我手头几台常用服务器的内存总和还多。更离谱的是&#xff0c;它不是一台机架式服务器…

2026/10/14 23:51:18 阅读更多 →
守株待兔式投资:构建路径图与触发哨兵的稳健交易体系

守株待兔式投资:构建路径图与触发哨兵的稳健交易体系

有一年年初&#xff0c;我给自己的投资研究体系编了个内部代号&#xff0c;就叫“投资-408”。编号本身没什么特殊含义&#xff0c;纯粹是项目管理习惯&#xff0c;但一整年跑下来&#xff0c;这个代号越来越像一句提醒&#xff1a;真正让账户曲线变得平滑的&#xff0c;往往不…

2026/10/14 23:50:17 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起&#xff1a;它到底想解决什么问题第一次看到"AnyPS5"这个标题&#xff0c;我脑子里冒出来的第一个念头是&#xff1a;这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述&#xff1a;Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师&#xff0c;我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性&#xff0c;实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景&#xff0c;也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间&#xff0c;确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中&#xff0c;这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →