题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
分析
接着前一天的分析工作做的,参考了书籍的分析。今天的分析过程:
使用一个番茄钟分析得出:
根据中序遍历的特点,左子树-根节点-右子树。既然已经输出了根节点(即给定的节点),则下一步的输出存在两种情况:有无右子树。
- 无右子树
根据中序遍历的特点,不断向上回溯,判断当前节点是否为父节点的右子节点,如果是,代表父节点已经输出过了,继续向上回溯,将父节点作为当前节点继续判断。
- 有右子树
则选出以当前节点的右子节点为根节点的左子树的最左端的叶子节点,输出该节点
复杂度分析
时间复杂度:O(logN) 空间复杂度:O(1)
边界分析
分析出的边界条件:空树,每次求节点的左节点、右节点、父节点时都应该判断是否存在,因为这个问题提交了好几次。
自己写的代码
/*
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode)
{
//判断是否是空子树
//判断有无右子树
if(pNode.right == null){
//回溯判断该节点是否为其父节点的右子节点
if(pNode.next == null){
return null;
}
TreeLinkNode fatherNode = pNode.next;
//未考虑这个情况,导致一直过不了
if(fatherNode.right == null){
return fatherNode;
}else{
while(fatherNode.right.equals(pNode)){
pNode = fatherNode;
if(pNode.next == null){
return null;
}
fatherNode = fatherNode.next;
}
return fatherNode;
}
}else{
//有右子树,求出其子树中左子树最左端的节点
pNode = pNode.right;
while(pNode.left != null){
pNode = pNode.left;
}
return pNode;
}
}
}
总结:
- 树的三种遍历方式还是不太熟悉;
- 题目的关键在于:判断是否存在右子树;不存在右子树的回溯和存在右子树时找到其右子树的左子树的最左端节点。
- 遇到的问题:在while循环的时候,如fatherNode.right.equals(pNode) ,我以为没有右子节点的话equals会返回false,其实它会返回空指针异常,这也是遇到好几次的错误!