题目
- 给定一棵二叉树和其中一个节点,如何找出中序遍历序列的下一个节点?
- 树中的节点除了有两个分别指向左、右子节点的指针,还要一个指向父节点的指针。
题目分析
本题中:一般应该先画出来二叉树的结构图、通过具体的例子找出中序遍历的下一个节点的规律,这样才有可能设计出可行的解决方法!
中序遍历的输出顺序是:左子树、根节点、右子树
举例分析
以下图为例,中序遍历是{d,b,h,e,i,a,f,c,g}
#// 普通二叉树
#// a
#// / \
#// b c
#// / \ / \
#// d e f g
#// / \
#// h i
思路:分三种情况,每一种都有对应的例子,能直观的理解
情况一:
- 若一个节点有右子树,那么它的下一个节点就是它右子树中的最左子节点。即,从右子节点出发一直沿着指向左子节点的指针,我们就可以找到它的下一个节点。
- 例: 节点 b 的下一个节点就是 h,节点 a 的下一个节点就是 f。
情况二:
- 若一个节点没有右子树。如果节点是它父节点的左节点,那么它的下一个节点就是它的父节点。
- 例: 节点 d 的下一个节点就是 b,节点f的下一个节点就是 c。
情况三:
-
若一个节点没有右子树。并且节点是它父节点的右节点,这时我们要沿着指向父节点的指针一直向上遍历,直到找到一个是它父节点的左节点的节点。如果存在这样的节点,那么这个节点的父节点就是我们要找的节点。
- 这个不好理解,看例子就明白:以节点 i 为例,节点 i 没有右子树,并且是它父节点的右子节点,符合这种要求,这时,我们沿着指向父节点的指针向上遍历,先到达节点 e。由于节点 e 是它父节点的右子节点,我们继续向上遍历,到达节点 b,节点 b 是其父节点的左子节点,因此这时节点 b 的父节点 a就是我们要找的下一个节点。
下面我们就可以是实现上面的思想了:
代码(Python)
class TreeLinkNode: # 指定二叉树,不仅有指向左右的指针,还有一个指向父节点的指针
def __init__(self,x):
self.val = x
self.right = None
self.left = None
self.next = None
class Solution:
def GetNext(self,pNode): # pNoed是二叉树的任意节点
if pNode is None: # 排空
return None
pNext = None # 定义一个节点pNext,也就是我们要找的下一个节点
if pNode.right: # 若节点pNoed存在右子树(情况一)
pNode = pNode.right # 将有节点赋值给pNoed
while pNode.left: # 若pNoed有左子节点,则把左子节点赋值给pNoed,并返回给pNext
pNode = pNode.left
pNext = pNode
else: # 若节点pNoed不存在右子树
if pNode.next and pNode.next.left == pNode: # 若节点pNoed是其父节点的左子节点(情况二)
pNext = pNode.next # 下一个节点就是其父节点
elif pNode.next and pNode.next.right == pNode: # 若节点pNoed是其父节点的右子节点(情况三)
pNode = pNode.next # 将父节点赋值给节点pNoed
while pNode.next and pNode.next.right == pNode: # 若节点pNoed是其父节点的右子节点,则一直向上遍历
pNode = pNode.next
if pNode.next: # 否则,节点pNoed是其父节点的左子节点,则返回其父节点
pNext = pNode.next
return pNext