Day57:二叉树的下一个结点
剑指Offer_编程题——二叉树的下一个结点
题目描述:
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
具体要求:
时间限制: C/C++ 1秒,其他语言2秒 空间限制: C/C++32M,其他语言64M
具体实现:
思路一: 在做题前,我们应该给大家介绍二叉树的中序遍历的相关知识:在前面的文章里给大家介绍过二叉树的遍历。因此,这里就给大家不详细介绍了。现在给大家介绍解题思路:我们根据对二叉树知识的了解,可以将情况分为三种:第一种:有右孩子,找到右孩子,循环遍历右孩子的左节点、第二种:没有右孩子,而且是根的左孩子,返回父亲节点、第三种:是父亲节点的右孩子,而且没有右孩子,则返回父亲节点的父节点等。具体的过程如下图所示:
因此,我们可以使用java来实现该思路:
public class Solution{
public TreeLinkNode GetNext(TreeLinkNode pNode){
if(pNode.right != null){
pNode = pNode.right;
while(pNode.left != null){
pNode = pNode.left;
}
return pNode;
}
while(pNode.next != null && pNode.next.right == pNode){
pNode = pNode.next;
}
return pNode.next;
}
}
代码效果图如图所示:
正如前面说的那样,如果在牛客网中,我们可以直接通过,但是如果是本地的编译器,则还需要定义其结点,具体结点的实现定义用java实现如下:
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
思路二: 根据前面对中序遍历的介绍,如果一个节点的右子树不为空,那么该节点的下一个节点是右子树的最左节点;那么需要首先判断给定的结点属于哪一种:如果它存在右子树,说明它是子树的父结点,下一个节点在其右子树中。如果右子树存在左孩子结点,那么下一个就是左孩子结点,否则说明它就是叶子结点,直接返回。如果它不存在右子树,说明当前结点为叶子节点:如果当前结点为右叶子,那么下一个就是它的父结点,即它next域指向的结点。如果它的父节点有左叶子,说明下一个节点就是父节点
② 否则,向上找第一个左链接指向的树包含该节点的祖先节点。
接下来我们分别用java和python两种语言来实现该思路: 1、首先我们用java实现该思路:
public class Solution{
public TreeLinkNode GetNext(TreeLinkNode pNode){
if(pNode.right != null){
TreeLinkNode node = pNode.right;
while(node.left != null){
node = node.left;
}
return node;
}else{
while(pNode.next !=null){
TreeLinkNode parent = pNode.next;
if(parent.left == pNode){
return parent;
}
pNode = pNode.next;
}
}
return null;
}
}
代码效果图如图所示:
2、接下来我们用Python将其实现:
class Solution:
def GetNext(self, pNode):
if pNode == None:
return None
if pNode.right:
pNode = pNode.right
while pNode.left:
pNode = pNode.left
return pNode
else:
while pNode.next:
if pNode == pNode.next.left:
return pNode.next
pNode = pNode.next
return None
代码效果图如图所示:
但是在本地编译器中我们还需要定义链表结构才能正常运行,具体用python定义链表结构实现如下:
class TreeLinkNode:
def __init__(self, pNode):
self.val = x
self.left = None
self.right = None
self.next = None
思路三: 无论是何种思路,首先要做的就是要知道二叉树的中序遍历。具体如下:
结合上图,我们可发现分成两大类: 1、有右子树的,那么下个结点就是右子树最左边的点;(eg:D,B,E,A,C,G) 2、没有右子树的,也可以分成两类:(a)是父节点左孩子(eg:N,I,L) ,那么父节点就是下一个节点 ;b)是父节点的右孩子(eg:H,J,K,M)找他的父节点的父节点的父节点…直到当前结点是其父节点的左孩子位置。如果没有eg:M,那么他就是尾节点。)。 具体我们用python将其实现:
class Solution:
def GetNext(self, pNode):
if not pNode:
return pNode
if pNode.right:
left1 = pNode.right
while left1.left:
left1 = left1.left
return left1
p = pNode
while pNode.next:
tmp = pNode.next
if tmp.left == pNode:
return tmp
pNode = tmp
代码效果图如图所示:
总结
本题主要通过二叉树的中序遍历来考察我们对二叉树遍历的应用,我们不仅要掌握二叉树的遍历,更要掌握其在不同的应用。本文给出了三种解题方法,并且这三种方法其实都是以中序遍历为依托的。另外我们还通过java和python将其实现。因此,我们在做题的时候,应该多次尝试各种方法,扩展自己的思维,写出优质的代码。总之,我们要继续加油,争取早日找到工作,Good Luck!!!
参考文献
[1] jiangjiane [2] Forlogen [3] DrogoZhang [4] 白马长枪儒雅将
- Spring cloud Zuul Filter 使用小经验
- Spring Cloud Eureka REST 接口
- Spring Cloud Eureka 控制台快速查看Swagger API文档
- Spring Cloud Feign 启动UnsatisfiedDependencyException
- Spring Cloud Zuul结合Smconf配置中心动态进行IP黑名单限制
- 高性能NIO框架Netty入门篇
- Spring Boot Web 静态文件缓存处理
- hbuilder 开发APP填坑经验
- hbuilder APP 定位提示苹果审核不通过
- hbuilder 开发5+ APP采坑记录
- Spring Cloud如何提供API给客户端
- 5分钟学会Spring Boot自定义属性和自动配置
- 创建一个Spring Security OAuth认证服务
- Zipkin和微服务链路跟踪
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法