
AcWing 19 二叉树的下一个节点
分情况讨论,先有右子树的情况,再无右子树的情况。 在有右子树的情况下,直接找到右子树的最左节点。 在无右子树的情况下向上查找,直到找到父节点的最左子树节点或到达根节点。 处理边界情况,例如根节点没有左孩子等情况。
发布日期:2021-05-28 16:30:10
浏览次数:28
分类:精选文章
本文共 1804 字,大约阅读时间需要 6 分钟。
找出二叉树节点在中序遍历序列中的后继节点是技术性的问题,需要对二叉树的结构和遍历特性有深入理解。以下从零开始详细分析解题思路,并提供最终优化后的代码实现。
首先,中序遍历的定义是:对于某个二叉树节点,从左子树访问完毕后,先访问该节点,最后访问右子树。所以,每个节点的后继节点可能是右子树的左most节点,或者父节点中的特定节点,具体情况因树的结构而异。
解题关键点分析
节点存在右子树:
- 如果当前节点有右子树,则其中序遍历后的后继节点应是该右子树的最左边节点。因为中序遍历顺序为左子树根节点右子树按照左至右顺序访问,所以右子树的最左边节点是在根节点过程之后的最先被访问到的节点。
缺少右子树:
- 当前节点没有右子树的情况下,该节点在中序遍历中的后继节点由其在父节点中的位置决定。若当前节点是父节点的左孩子,则其中序遍历后的父节点可能就是后继节点;若当前节点是父节点右孩子,则需要继续向上查找父节点的左孩子,直到找到一个节点或到达根节点。
- 继续向上查找的逻辑实际上是回溯过程中的处理方式,因为在缺少右子树的情况下,后继节点只能在父节点或其上层节点电子之中找到。
下面的代码实现将分两步骤处理:
处理有右子树的情况:
- 递归或迭代的方式移动到右子树的最左节点,返回该节点。
处理无右子树的情况:
- 逆向查找上层节点,找到是否是左孩子,若是,则当前父节点就是后继;否则,继续向上查找,直到找到父节点。
- 最坏情况下,需要回到根节点,此时检查根节点是否是左孩子,若有左孩子,则返回根节点的左孩子。
代码实现优化
为了保证代码的可执行性和设定好的维护性,接下来提供一个清晰的代码模板:
nodeTS { val: number; left: nodeTS | null; right: nodeTS | null; father: nodeTS | null;}class Solution { inorderSuccessor(p: nodeTS): nodeTS | null { // 如果存在右子树,则后继节点是右子树的左most节点 if (p.right) { let current = p.right; while (current.left) { current = current.left; } return current; } // 如果没有右子树,则向上查找上层节点 // 找到第一个不作为右孩子的父节点 while (p && (p.father?.right === p)) { p = p.father; } return p.father?.left ?? null; // 需要注意的情况是,当p位于根节点的右侧时,它没有父亲的情况下,该函数如何处理 }}
需要注意的是:
当节点p在根节点的右侧,并且根节点的左孩子存在时,函数返回根节点的左孩子。
如果根节点没有左孩子,则函数会返回null。
终止条件应处理好,以免进入死循环。例如,当p是根节点时,在无右孩子的情况下,函数已经返回正确结果。
前后验证
我可以利用示例二叉树:
2 / \ 1 3
验证函数的工作流程:
对于节点2:
- 检查右射子树是否存在,是的,进入右子树,移动到3的左节点,此时3没有左子树,返回3。
对于节点1:
- 检查右射子树不存在,开始猜上层节点:
- 1是2的左子树,返回2。
- 检查右射子树不存在,开始猜上层节点:
对于节点3:
- 没有右子树,进入上层查找:
- 3是2的右子树,
- 继续向上到达根节点2,
- 2不是左子树,但根节点的左子树存在,
- 返回根节点的左子树节点1。
- 没有右子树,进入上层查找:
那么测试情况显示函数是正确的。
总结
通过以下方法可以系统地解决该问题:
这个方法论在面对二叉树问题时,是解决遍历相关题意的通用方法,具有较好的扩展性和可维护性。
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年04月28日 09时19分22秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Android 架构组件 – 让天下没有难做的 App
2019-03-13
启动MongoDB出现1053错误
2019-03-13
Flask操作SQLAlchemy
2019-03-13
网络对抗技术-Exp2-后门原理与实践 20181314
2019-03-13
能解决数据可视化大屏需求的3款可视化工具
2019-03-13
欢迎来到小迪博客
2019-03-13
【Altium Designer21】工作栏中文解析
2019-03-13
[87]用secureCRT连接虚拟机中的Ubuntu系统,出现“远程主机拒绝连接”错误
2019-03-13
Shell脚本防DNS攻击检测并删除肉机IP
2019-03-13
如何在VSCode中定制JSON的IntelliSense
2019-03-13
椭圆曲线的定义
2019-03-13
多代理区块链框架客户端的操作
2019-03-13
RSA操作中的公钥和私钥的生成
2019-03-13
C#从1打印到100再打印到1-递归的应用
2019-03-13
go语言中类的继承和方法的使用
2019-03-13
Ubuntu 修改权限的操作
2019-03-13
caffe训练的时候遇到的text-format 错误解决方案。
2019-03-13
Java 8新特性(一):Lambda表达式
2019-03-13
ZOJ问题(坑死了)
2019-03-13
Little Zu Chongzhi's Triangles
2019-03-13