题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
思路:
PS:
中序遍历 | 首先处理左子树,然后是当前结点,最后是右子树 |
---|---|
先序遍历 | 先处理当前结点,再处理左右子结点 |
后序遍历 | 先处理处理左右子结点,再处理当前结点 |
如上图,中序遍历的顺序为:d-b-h-e-i-a-f-c-g
1、如果当前结点有右子树,即找到右子树的最左子树。直到左子树为空,则为当前结点。
例如对于a,下一个结点为f;对于b,下一个结点为h。
2、若当前结点没有左右子结点,则需判断当前结点与父节点的关系。
- 父节点不存在,则返回null;
- 当前结点为父节点的左子节点,则下一个结点就是父节点;
- 当前结点为父节点的右子节点,情况较为复杂。
需要不断向上查询,直到找到当前节点作为父节点的左子结点,此时的父节点即为下一个结点。
如果一直查找不到,则下一个节点为null。
例如为了找到g的下一个结点,不断向上找父节点,发现没有作为左子结点的结点,则下一个为Null。
而对于节点 i,不断向上找父节点,直到找到结点 a,结点b是结点a 的左子结点,所以b 是下一个结点。
实现代码:
小白版本
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode)
{
while(pNode != null)
{
//如果没有右子树
if(pNode.right == null)
{
//为父节点的左结点,则下一个为父节点
if(pNode.next != null && pNode == pNode.next.left)
{
return pNode.next;
}
//为父节点的右节点,较为复杂
else if(pNode.next != null && pNode == pNode.next.right)
{
//找到作为左子节点的父节点
while(pNode.next != null)
{
while(pNode == pNode.next.left)
{
return pNode.next;
}
pNode = pNode.next;
}
//找不到则为null
return null;
}
//没有父节点
else
return null;
}
//如果有右子树
else
{
//找到最左子树
while(pNode.right.left != null)
{
pNode.right = pNode.right.left;
}
//直到找不到左子树,即当前结点
return pNode.right;
}
}
return null;
}
}
大牛版本:
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode node)
{
if(node==null)
return null;
if(node.right!=null)
{ //有右子树
node=node.right;
while(node.left!=null)
{
node=node.left;
}
return node;
}
while(node.next!=null)
{
//父节点
if(node.next.left==node)
return node.next;
node=node.next;
}
return null;
}
}