这题有两种解法,暴力法和直接寻找法。
暴力法的大致思路是,先根据给出的节点寻找这棵树的根节点,然后从根节点开始中序遍历加入List集合中。最后遍历集合找到pNode的下一个节点。
代码如下:
/*暴力方法*/
List<TreeLinkNode> list = new List<TreeLinkNode>();
public TreeLinkNode GetNext(TreeLinkNode pNode)
{
if (pNode == null) return null;
TreeLinkNode father = pNode;
while (father.next != null)
{
father = father.next;
}
InOrder(father);
for (int i = 0; i < list.Count; i++)
{
if (list[i] == pNode)
{
if (i == list.Count - 1)
{
return null;
}
return list[i + 1];
}
}
return null;
}
public void InOrder(TreeLinkNode root)
{
if (root == null)
{
return;
}
InOrder(root.left);
list.Add(root);
InOrder(root.right);
}
直接寻找法这个就神了,通过找规律可以找到给定节点的下一节点。
先给出参考图,图来自牛客官方题解:
节点的遍历顺序如图序号所标注的那样。
我们将给定节点分为以下几种情况(第三种情况有点绕,各位多看几遍):
1.有右孩子,下一结点是右子树中的最左孩子。
2.无右孩子,且结点是该结点父结点的左孩子,则下一结点是该结点的父结点
3.无孩子,且结点是该结点父结点的右孩子,则我们一直沿着父结点追朔,直到找到某个结点是其父结点的左孩子,如果存在这样的结点,那么这个结点的父结点就是我们要找的下一结点。
/*直接寻找下一节点法*/
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;
}
while(pNode.next!=null)
{
TreeLinkNode father=pNode.next;
if(father.left==pNode)
{
return father;
}
pNode=pNode.next;
}
return null;
}
顺便吐槽一下,这里的树类里边节点的父亲叫next???