JZ8 二叉树的下一个结点

描述

给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。下图为一棵有9个节点的二叉树。树中从父节点指向子节点的指针用实线表示,从子节点指向父节点的用虚线表示



示例:

输入:{8,6,10,5,7,9,11},8

返回:9

解析:这个组装传入的子树根节点,其实就是整颗树,中序遍历{5,6,7,8,9,10,11},根节点8的下一个节点就是9,应该返回{9,10,11},后台只打印子树的下一个节点,所以只会打印9,如下图,其实都有指向左右孩子的指针,还有指向父节点的指针,下图没有画出来

分析

初拿到这道题,很明显看出是一个二叉树的中序遍历就可以解决的问题,但是仔细看了题目之后,发现,题目会给两个参数,而这两个参数组装成的是一个二叉树节点(可以是其中树的任意节点),这样的话,如果使用普通的遍历方法直接做,就会有问题,需要多一步遍历这个节点的next找到整棵树的根节点,之后使用dfs进行中序遍历得到结果。

代码

      /**
* JZ8 二叉树的下一个结点
* @param pNode
* @return
*/
public TreeLinkNode GetNext(TreeLinkNode pNode) {
//提出题目中要求对比的值
Integer value = pNode.val;
//通过不断的寻找next找到整棵树的根节点
while (pNode.next != null) {
pNode = pNode.next;
}
//结果队列
Queue<TreeLinkNode> queue = new LinkedList<>();
//dfs遍历使用的栈,储存没有遍历过的节点用
Stack<PosNode> treeStack = new Stack<>();
//根节点
PosNode rootNode = new PosNode(pNode);
//根节点加入栈
treeStack.push(rootNode);
//如果所有节点都已经遍历过就跳出循环
while (treeStack.size() > 0) {
//中序遍历,先遍历左子树
if (treeStack.peek().node.left != null && treeStack.peek().visitLeft == false) {
PosNode posNode = new PosNode(treeStack.peek().node.left);
//证明左子树访问过
treeStack.peek().visitLeft = true;
treeStack.push(posNode);
}else {
//把节点值值存储在结果队列中
queue.offer(treeStack.peek().node);
//证明左子树访问过
treeStack.peek().visitLeft = true;
//开始遍历右子树
if (treeStack.peek().node.right != null && treeStack.peek().isVisitRight == false) {
PosNode posNode = new PosNode(treeStack.peek().node.right);
treeStack.peek().isVisitRight = true;
treeStack.push(posNode);
}else {
//如果右子树也遍历过或者为空的话
treeStack.peek().isVisitRight = true;
//通过出栈寻找左右子树都没有遍历过的节点
while (treeStack.size() != 0 && treeStack.peek().isVisitRight == true && treeStack.peek().visitLeft == true)
treeStack.pop();
}
}
} //存储的中序遍历结果进行值的比较找出结果
while (queue.size() != 0) {
if (queue.peek().val != value) {
queue.poll();
}else {
queue.poll();
return queue.peek();
}
} //找不到的话返回空值
return null;
} /**
* 保存节点以及记录节点的左右子树是否访问过的表质量
*/
class PosNode{
TreeLinkNode node;
boolean visitLeft = false;
boolean isVisitRight = false; PosNode(TreeLinkNode node) {
this.node = node;
}
}

总结

需要熟练使用代码来遍历二叉树,本人的方法使用内存占用较高,后续可以去除结果队列,直接在遍历中使用标志量记录结果返回。

剑指offer:JZ8 二叉树的下一个结点的更多相关文章

  1. 【剑指Offer】二叉树的下一个结点 解题报告(Python)

    [剑指Offer]二叉树的下一个结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...

  2. 【Java】 剑指offer(7) 二叉树的下一个结点

    本文参考自<剑指offer>一书,代码采用Java语言.  更多:<剑指Offer>Java实现合集 题目 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?  ...

  3. Go语言实现:【剑指offer】二叉树的下一个结点

    该题目来源于牛客网<剑指offer>专题. 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回. 注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. Go语 ...

  4. 剑指Offer 57. 二叉树的下一个结点 (二叉树)

    题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 题目地址 https://www.nowcoder.c ...

  5. [剑指Offer] 57.二叉树的下一个结点

    题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. /* struct TreeLinkNode { in ...

  6. 剑指offer——06二叉树的下一个节点

    题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针.   题目的意思是,在一颗二叉树的中序遍历中,给出其中一 ...

  7. 剑指offer57:二叉树的下一个结点

    1 题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 2 思路和方法 中序遍历,下一个结点有两种情况 a ...

  8. [剑指Offer]8-二叉树的下一个节点

    链接 https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPa ...

  9. 【剑指offer】面试题 8. 二叉树的下一个结点

    面试题 8. 二叉树的下一个结点 NowCoder 题目描述 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指 ...

随机推荐

  1. Kafka内外网访问

    本文介绍了Kafka内外网访问的设置. kafka的两个配置listeners和advertised.listeners listeners kafka监听的网卡的ip,假设你机器上有两张网卡,内网1 ...

  2. Linux下cat命令的使用

    1.普通用法-->查看文件内容 cat file_name 查看文件时的相关参数: 1.cat f1.txt,查看f1.txt文件的内容. 2.cat -n f1.txt,查看f1.txt文件的 ...

  3. noip模拟29

    这次终于是早上考试了 早上考试手感不错,这次刷新了以前的最高排名- %%%cyh巨佬 \(rk1\) %%%CT巨佬 \(t2\) 90 纵观前几,似乎我 \(t3\) 是最低的-- 总计挂分10分, ...

  4. 第04课:使用 VS 管理开源项目

    本节课将介绍 Redis 项目在 Linux 系统中使用 gdb 去调试,这里的调试环境是 CentOS 7.0,但是通常情况下对于 C/C++ 项目我一般习惯使用 Visual Studio 去做项 ...

  5. ubuntu 20.04 发邮件配置

    安装sendmail后,发邮件一直没有成功,因此卸载sendmail后,安装heirloom-mailx. # unbuntu 18.04和20.04移除了heirloom-mailx,需要另外配置软 ...

  6. Java-Bean Validation后端校验总结

    Validation Information resource: SpringBoot Docs: 2.8.9. @ConfigurationProperties Validation url: ht ...

  7. Emit优化反射(属性的设置与获取)

    在频繁的通过反射来设置和获取属性的值时是比较耗时的,本章通过Emit技术优化反射来提高获取和设置属性值的效率 一.实现代码: /// <summary> /// 设置器委托 /// < ...

  8. Markdown时序图--基础语法

    时序图 ​ 序列图是一种交互图,它显示了流程以何种顺序相互操作. Mermaid可以渲染序列图,如下定义. sequenceDiagram Alice->>John:Message Hel ...

  9. 痞子衡嵌入式:原来i.MXRT1xxx系列里也暗藏了Product ID寄存器

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1xxx系列里暗藏的Product ID寄存器. MCU 厂商在定义一个产品系列时,通常是会预先规划产品发展路线的(即会有一 ...

  10. Spring Boot中使用@Async的时候,千万别忘了线程池的配置!

    上一篇我们介绍了如何使用@Async注解来创建异步任务,我可以用这种方法来实现一些并发操作,以加速任务的执行效率.但是,如果只是如前文那样直接简单的创建来使用,可能还是会碰到一些问题.存在有什么问题呢 ...