江苏网站建设系统方案个人网页设计论文正文

张小明 2025/12/28 19:32:07
江苏网站建设系统方案,个人网页设计论文正文,长沙市人才网,在家做网站或ps挣钱接活最近在做 LeetCode 450#xff08;删除二叉搜索树中的节点#xff09;时#xff0c;我写出了一版执行用时 0ms#xff0c;击败 100% 用户的代码。 从算法效率上讲#xff0c;它是完美的#xff1a;纯指针操作#xff0c;没有递归开销#xff0c;逻辑硬核。 但从工程角度…最近在做 LeetCode 450删除二叉搜索树中的节点时我写出了一版执行用时 0ms击败 100% 用户的代码。 从算法效率上讲它是完美的纯指针操作没有递归开销逻辑硬核。 但从工程角度讲它是十足的垃圾代码可能下周我自己都看不明白我写的什么玩意了。今天这篇博客我想通过复盘这段代码聊聊如何把代码从“能跑”进化到“能读”。第一阶段原始代码我的核心思路非常直接物理断开与重连。 不搞递归那种值拷贝直接找到节点找到它的前驱左子树最右节点把前驱拎出来物理替换掉目标节点。这是我提交的原始版本已通过所有测试用例// 此代码虽然性能极致但是问题一堆写得一塌糊涂。 class Solution { public: TreeNode* deleteNode(TreeNode* root, int key) { // 【段落 1】 处理空节点的情况 if (!root) { return nullptr; } // 【段落 2】 处理key节点是根节点的情况 // 这里的逻辑没有父节点直接操作 root if (root-val key) { if (!root-left !root-right) { return nullptr; } else if (!root-left root-right) { return root-right; } else if (root-left !root-right) { return root-left; } else if (root-left root-right) { //复杂的双子节点处理逻辑 TreeNode* old1 root;// 【角色被删节点】 (这里就是root本身) TreeNode* old2 root;// 【角色前驱节点的父节点】 (初始跟被删节点一样) root root-left; while (root-right) {//潜在巨雷 root去当游标了 old2 root; root root-right; } if (old1 old2) { //说明这个左节点就是左子树最右的节点了 root-right old1-right; return root; } else if (old1 ! old2) { old2-right nullptr; root-right old1-right; TreeNode* t root; while (t-left) { t t-left; } t-left old1-left; return root; } } } // 【段落 3】 key节点不是根节点的情况 TreeNode* old0 root; // 保存原始根 (最后要返回它) TreeNode* old1 root; // 【角色被删节点的父节点】 (上半部分没有因为上半部分没父节点) TreeNode* old2 root; // 【角色被删节点 / 目标节点】 (初始是root后面会变成目标) // 1. 先找到要删除的节点 while (root root-val ! key) {//潜在巨雷 root去当游标了 if (root-val key) { old1 root;// old1 紧跟 root 充当父节点 root root-left; } else { old1 root;// old1 紧跟 root 充当父节点 root root-right; } } // 没找到直接返回 if (!root) { return old0; } // 到这里root 指向的就是【要被删除的节点】 // 下面的逻辑开始处理删除 root (即 old2) 的操作 // 情况 1: 叶子节点 if (!root-left !root-right) { if (old1-left root) { old1-left nullptr; return old0; } else { old1-right nullptr; return old0; } } // 情况 2: 只有右孩子 else if (!root-left root-right) { if (old1-left root) { old1-left root-right; return old0; } else { old1-right root-right; return old0; } } // 情况 3: 只有左孩子 else if (root-left !root-right) { if (old1-left root) { old1-left root-left; return old0; } else { old1-right root-left; return old0; } } // 情况 4: 左右孩子都有 (最晕的地方来了) else if (root-left root-right) { // 此时 root 是【要被删除的节点】 old2 root;// 【角色被删节点】 -- 对应上半部分的 old1 TreeNode* old3 root;// 【角色前驱节点的父节点】 -- 对应上半部分的 old2 // 开始寻找前驱 (左子树的最右节点) root root-left; while (root-right) { old3 root;// old3 紧跟记录前驱的父亲 root root-right; } // 循环结束后root 变成了【前驱节点】(用来顶替被删节点的那个人) // 下面的逻辑和上半部分是完全镜像的只是变量名下标1了 // 特例前驱节点的父节点 就是 被删节点本身 (即左子树没有右分支) if (old3 old2) { if (old1-left old2) { root-right old2-right; old1-left root; return old0; } else { root-right old2-right; old1-right root; return old0; } } // 通用情况前驱节点在深处 // 此时old1(爷爷), old2(被删), old3(前驱父), root(前驱) else if (old3 ! old2) { old3-right nullptr; root-right old2-right; TreeNode* t root; while (t-left) { t t-left; } t-left old2-left; if (old1-left old2) { old1-left root; return old0; } else { old1-right root; return old0; } return old0; } } return root; } };第二阶段局部分析这代码就是我一边想一边写的产物脑子里在想各种情况如何处理然后就实时写出各分支游标、变量都是随时需要随时定义随时使用。等写完我自己再复盘的时候都没绷住虽然能通过但是实在是太有槽点了以至于我必须新开一篇blog记录一下我到底是怎么写出这种代码以及该如何改进的。我们一行行来分析问题出在哪1. 变量命名陷阱TreeNode* old0 root; TreeNode* old1 root; TreeNode* old2 root; TreeNode* old3 root; // 在某些分支里还有 old3问题old家族大团结我的小巧思。但old是什么意思旧的老的old0到old3之间是什么关系这种命名迫使阅读者必须在脑子里维护一张映射表old1父亲, old2目标…。一旦代码逻辑变复杂这张表瞬间就会崩塌。代码失去了自解释能力。更要命的是上下两部分的old1、old2甚至代表的含义都不一样。2. 逻辑分裂if (root-val key) { ... } // 处理 Root // ... while (root root-val ! key) { ... } // 处理非 Root问题上半部分和下半部分的删除逻辑叶子、单边、双边是完全一样的仅仅因为根节点没有父节点我就把代码复制了一遍。这导致任何一次逻辑修正比如修复 BST 断链 bug都需要改两个地方漏改一处就是事故。3. 指针复用混乱while (root root-val ! key) { root root-left; // root 变成了游标 } return old0; // 最后不得不返回保存的 old0问题root指针在函数里身兼数职它是树的入口是遍历的游标又是某些分支的返回值。这种“一鱼多吃”的做法极大地增加了认知负荷。输入参数应尽量保持只读或语义稳定。4. 控制流层层递进代码缩进呈现可怕的箭头状。问题if套ifelse连else。这种深层嵌套掩盖了主要逻辑流。第三阶段架构调整在开始改代码之前我们需要先在脑海里重构模型。如何消除 Root 和非 Root 的区别如何让逻辑变清晰 答案是逻辑分层。原始代码是“边找边删”重构代码应该是流水线作业Search定位统一找到目标节点target和它的父节点parent。Decide决策决定谁来接班replacement。Link缝合统一执行指针连接操作。核心在算法眼里Root 只是一个parent为nullptr的普通节点。引入parent变量且专门处理一下parent为nullptr时的情况两套逻辑瞬间就能合并为一套。第四阶段重构基于上述分析保留我核心的“物理断开前驱”的高效逻辑重构后的代码如下。请对比阅读class Solution { public: TreeNode* deleteNode(TreeNode* root, int key) { // 1. 处理空树减少一层嵌套 if (!root) return nullptr; // 2. 统一查找逻辑 // 使用语义化变量target (目标), parent (父亲) TreeNode* target root; TreeNode* parent nullptr; while (target target-val ! key) { parent target; // 父节点紧跟其后 if (key target-val) { target target-left; } else { target target-right; } } // 没找到直接返回 if (!target) return root; // 3. 决定谁来接班 (replacement) TreeNode* replacement nullptr; // 情况 A: 左右双全 (最复杂的逻辑保留原版的高效思路) if (target-left target-right) { // 语义化变量predecessor (前驱), predParent (前驱的父亲) TreeNode* predecessor target-left; TreeNode* predParent target; // 寻找左子树的最右节点 while (predecessor-right) { predParent predecessor; predecessor predecessor-right; } // 处理前驱的“身后事” if (predParent ! target) { predParent-right predecessor-left; // 爷爷接管孙子的左孩子 predecessor-left target-left; // 前驱接管目标的左臂膀 } // 前驱接管目标的右臂膀 predecessor-right target-right; // 选定接班人 replacement predecessor; } // 情况 B: 只有左孩子 else if (target-left) { replacement target-left; } // 情况 C: 只有右孩子 else if (target-right) { replacement target-right; } // 情况 D: 叶子节点 (replacement 保持为 nullptr) else { replacement nullptr;//这一块可以不写写也只是为了清晰一点。 } // 4. 【缝合阶段】统一执行连接 // 这一步彻底消除了 Root 和 非 Root 的代码重复 if (!parent) { // 如果没有父亲说明删的是 Root直接换头 root replacement; } else { // 如果有父亲让父亲指向新的接班人 if (parent-left target) { parent-left replacement; } else { parent-right replacement; } } // 此时整棵树的结构已完整统一返回 return root; } };总结从old0/old1/old2/old3到target/parent/predecessor/predParent从“两坨逻辑”到“一条流水线”。这次重构没有改变算法的时间复杂度依然是 0ms但它改变了代码的生命周期。原始代码写完即死难以维护我自己写自己看都绷不住。重构代码逻辑清晰结构稳健任何人接手捋捋都能看懂。写出计算机能跑的代码只能算是一种本能而写出让人能读懂最起码能让未来的自己看懂的代码(难绷)才是真正的本事。以前看到过一句话好看的武器一定好用。我想好的代码也应该具备这种品质优雅美丽高效简洁。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

平乡县网站建设肇庆 网站建设 骏域网站

BetterNCM终极指南:网易云音乐插件管理器完全安装手册 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 还在为网易云音乐功能单一而苦恼吗?BetterNCM插件管理器将…

张小明 2025/12/28 19:31:32 网站建设

企业网站优化设计应该把什么放在首位做ppt找素材的网站

在当今AI技术飞速发展的时代,语音合成技术正经历着革命性的变革。Chatterbox TTS作为Resemble AI推出的开源多语言语音合成系统,正在重新定义我们对智能语音的认知。这款基于0.5B参数Llama架构的先进模型,不仅在音质表现上媲美商业闭源产品&a…

张小明 2025/12/28 19:30:23 网站建设

wordpress整站代理网络软件

FaceFusion与Tabby SSH连接:远程操控GPU服务器进行批量处理 在影视后期、短视频创作和虚拟内容生成领域,一个越来越常见的挑战是:如何在有限的本地算力条件下,高效完成高精度的人脸替换任务?许多创作者发现&#xff0c…

张小明 2025/12/28 19:29:48 网站建设

开发一个进销存app需要多少钱网络优化师

Sigma规则转换后端实战:企业级深度优化与性能进阶 【免费下载链接】sigma 项目地址: https://gitcode.com/gh_mirrors/sig/sigma 核心问题:为什么90%的Sigma规则转换会失败? 在实际企业部署中,Sigma规则的转换成功率往往…

张小明 2025/12/28 19:28:40 网站建设

做家教网站资质营销型网站的作用是

高级纹理与着色技术 在城市仿真软件中,高级纹理与着色技术是实现高质量视觉效果的关键。本节将详细介绍如何在CityEngine中应用这些技术,以提升城市模型的逼真度和视觉吸引力。我们将从纹理映射、材质编辑、着色器编程等方面入手,结合具体实例…

张小明 2025/12/28 19:28:05 网站建设

淘宝网站代理怎么做教育网站搭建

Galacean Effects终极指南:打造流畅Web动画的完整解决方案 【免费下载链接】effects-runtime It can load and render cool animation effects 项目地址: https://gitcode.com/gh_mirrors/ef/effects-runtime 在当今数字化体验时代,Web动画已成为…

张小明 2025/12/28 19:27:30 网站建设