JZ57 二叉树的下一个结点
题目描述:
给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。下图为一棵有9个节点的二叉树。树中从父节点指向子节点的指针用实线表示,从子节点指向父节点的用虚线表示
输入描述:
输入分为2段,第一段是整体的二叉树,第二段是给定二叉树节点的值,后台会将这2个参数组装为一个二叉树局部的子树传入到函数GetNext里面,用户得到的输入只有一个子树根节点
返回值描述:
返回传入的子树根节点的下一个节点,后台会打印输出这个节点
示例:
示例0:
输入:{8,6,10,5,7,9,11},8
返回:9
解析:这个组装传入的子树根节点,其实就是整颗树,中序遍历{5,6,7,8,9,10,11},根节点8的下一个节点就是9,应该返回{9,10,11},后台只打印子树的下一个节点,所以只会打印9,如下图,其实都有指向左右孩子的指针,还有指向父节点的指针,下图没有画出来
示例1
输入:
{8,6,10,5,7,9,11},8
返回值:
9
示例2
输入:
{8,6,10,5,7,9,11},6
返回值:
7
示例3
输入:
{1,2,#,#,3,#,4},4
返回值:
1
示例4
输入:
{5},5
返回值:
"null"
说明:
不存在,后台打印"null"
题解:
方法一:找到树根然后中序遍历
1.思路
既然题中的所给条件可以回溯到树根,那么直接中序遍历即可,将结果存入数组中,最后在遍历一次数组进行查找。
2.复杂度:
时间复杂度:O(3*n):回溯根O(n),中序遍历O(n),最后查找O(n)
空间复杂度:O(n)
3.代码:
/*
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
*/
import java.util.ArrayList;
public class Solution {
ArrayList<TreeLinkNode> array = new ArrayList<>();
void InOrder(TreeLinkNode root){
if(root!=null){
InOrder(root.left);
array.add(root);
InOrder(root.right);
}
}
public TreeLinkNode GetNext(TreeLinkNode pNode) {
// 方法
if(pNode == null)
return null;
TreeLinkNode root = pNode;
while(root.next!=null){
root = root.next;
}
InOrder(root);
root = null;
for(int i=0; i<array.size()-1; i++){
if(array.get(i) == pNode)
root = array.get(i+1);
}
return root;
}
}
方法二:找规律
1.思路
如图所示下一个结点只有这几种情况:
1.当前节点有右子树,它的下一个结点就是右子树的最左节点。符合这个条件的有【8,6,10】
2.没有右子树,但是有父节点而且它属于父节点的左子树,那么它的下一个结点就是父节点。符合这个条件的有【5,9】
3.没有右子树,但是有父节点而且它属于父节点的右子树,那么需要一直向根遍历,知道不符合条件3,如果找到根节点还是符合条件3,那就下一个结点为null,符合这个条件的有【11】;如果找到不符合调节3的节点用1,2找出下一个结点,符合这个条件的有【7】
2.复杂度:
时间复杂度:O(n)
空间复杂度:O(1)
3.代码:
/*
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
*/
import java.util.ArrayList;
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode) {
// 方法:直接找下一个
if(pNode == null)
return null;
if(pNode.right != null){
pNode = pNode.right;
while(pNode.left != null){
pNode=pNode.left;
}
return pNode;
}
if(pNode.next!= null && pNode.next.left==pNode){
return pNode.next;
}
while(pNode.next!=null && pNode.next.right==pNode){
pNode = pNode.next;
}
if(pNode.next!=null){
return pNode.next;
}else{
return null;
}
}
}