描述
题目描述
给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。
输入描述:
输入分为2段,第一段是整体的二叉树,第二段是给定二叉树节点的值,后台会将这2个参数组装为一个二叉树局部的子树传入到函数GetNext里面,用户得到的输入只有一个子树根节点
返回值描述:
返回传入的子树根节点的下一个节点,后台会打印输出这个节点
示例
输入:{8,6,10,5,7,9,11},8
返回值:9知识点:二叉树,遍历
难度:⭐⭐
题解
解题思路
对于二叉树的问题,无非就是遍历、递归、套框架。
这道题最容易想到的就是暴力遍历,根据结点的值找到结点的下一个结点,好在二叉树不存在重复结点,此法可行,但不是考察重点和最优解。
最有解法是通过使用中序遍历的特性,分类模拟,从而分情况找到结点处于不同状态下的下一个结点的解法。
方法一:特性模拟
图解

算法流程:
- 1、如果目标结点不是叶子结点
- 则在中序遍历中,下一个结点为当前结点的右子树的最左叶子结点
- 循环遍历,找到当前子树的最左叶子结点
- 2、如果目标结点是叶子结点而不是根节点,则需要向上寻找父节点
- 结点是父节点的左子结点,则在中序遍历中,目标结点的下一个结点就是父节点
- 结点是是父节点的右子结点,则在中序遍历中,还要继续寻找, 直到满足当前结点是父节点的左子结点
Java 版本代码如下:
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode) {
if(pNode == null) {
return null;
}
// 1、如果目标结点不是叶子结点
// 则在中序遍历中,下一个结点为当前结点的右子树的最左叶子结点
if(pNode.right != null) {
pNode = pNode.right;
// 循环遍历,找到当前子树的最左叶子结点
while(pNode.left != null) {
pNode = pNode.left;
}
return pNode;
}
// 2、目标结点是叶子结点而不是根节点,则需要向上寻找父节点
while(pNode.next != null) {
TreeLinkNode parentNode = pNode.next;
// 是父节点的左子结点,则在中序遍历中,目标结点的下一个结点就是父节点
if(parentNode.left == pNode) {
return parentNode;
} else {
// 是父节点的右子结点,则在中序遍历中,还要继续寻找
// 直到满足当前结点是父节点的左子结点
pNode = pNode.next;
}
}
return null;
}
} Python 版本代码如下:
class Solution:
def GetNext(self, pNode):
# write code here
if not pNode:
return pNode
# 1、如果目标结点不是叶子结点
while pNode.right:
p=pNode.right
# 则在中序遍历中,下一个结点为当前结点的右子树的最左叶子结点
if p.left:
p=p.left
return p
# 2、目标结点是叶子结点而不是根节点,则需要向上寻找父节点
while pNode.next:
p=pNode.next
# 是父节点的右子结点,则在中序遍历中,还要继续寻找,直到满足当前结点是父节点的左子结点
if p.left==pNode:
return p
pNode=p
复杂度分析:
时间复杂度 O(N):最坏的情况是遍历所有结点
空间复杂度 O(1):没有用到类似数组的类型数据
方法二:暴力查找
算法流程:
根据二叉树结点都是唯一值的特性,通过目标结点的值查找目标结点,便能找到中序遍历的下一个结点
Java 版本代码如下:
import java.util.*;
public class Solution {
static ArrayList<TreeLinkNode> list = new ArrayList<>();
public TreeLinkNode GetNext(TreeLinkNode pNode){
TreeLinkNode par = pNode;
while(par.next != null){
par = par.next;
}
InOrder(par);
for(int i=0;i<list.size();i++){
if(pNode == list.get(i)){
return i == list.size()-1?null:list.get(i+1);
}
}
return null;
}
void InOrder(TreeLinkNode pNode){
if(pNode!=null){
InOrder(pNode.left);
list.add(pNode);
InOrder(pNode.right);
}
}
}复杂度分析:
时间复杂度 O(N):最坏的情况是遍历所有结点
空间复杂度 O(N):用到了集合,N 为 List 长度

京公网安备 11010502036488号