剑指offer笔记5:二叉树的下一个节点(P65)
题目:二叉树的下一个节点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。二叉树节点的定义如下:
class TreeLinkNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
self.next = None
问题分析
以这个二叉树为例进行分析:
找出二叉树下一个节点分三种情况:
- 该节点有右子树
如图中的节点 b ,要找出 b 的下一节点。根据中序遍历的顺序,b 的下一节点是 h ,即 b 的右子树中最左边的节点。与 b 类似的节点还有 a 、e 、c 。 - 该节点没有右子树,且为其父节点的左子节点
如图中的节点 d ,要找出 d 的下一节点。根据中序遍历的顺序,d 的下一节点是 b ,即 d 的父节点。与 d 类似的节点还有 h 、f 。 - 该节点没有右子树,且为其父节点的右子节点
如图中的节点 i ,要找出 i 的下一节点。根据中序遍历的顺序,i 的下一节点是 a ,即 i 节点所属的最小左子树的父节点。与 i 类似的节点还有 g 。其中 g 不在左子树里,因此 g 没有下一节点。
总结一下步骤:
- 该节点有右子树
从该节点的右子节点出发一直沿着左指针走,找到其右子树中最左边的节点,即为该节点的下一节点。 - 该节点没有右子树,且为其父节点的左子节点。
通过该节点指向父节点的指针找到其父节点,即为该节点的下一节点。 - 该节点没有右子树,且为其父节点的右子节点。
通过该节点指向父节点的指针一直往上遍历,直到找到某节点为其父节点的左子节点为止,其父节点为该节点的下一节点。
python 代码
def GetNext(self, pNode):
# write code here
if pNode is None:
return None
next_node = None
if pNode.right is not None:
# 若该节点有右子节点
next_node = pNode.right
while next_node.left is not None:
# 顺着右子节点的左边一直向下走,找到右子树最左边的节点
next_node = next_node.left
elif pNode.next is not None:
# 若该节点没有右子节点,并且其有父节点
current_node = pNode
parent_node = pNode.next
while parent_node is not None and current_node is parent_node.right:
# 若当前节点为其父节点的右子节点时,顺着指向其父节点的指针向上走
current_node = parent_node
parent_node = parent_node.next
# 直到找到一个节点,为其父节点的左子节点为止
# 若在查找过程中,直到根时,还没有为其父节点的左子节点,则返回一个None,这个可与空的父节点合并
next_node = parent_node
# 下一节点为父节点,包括三种可能性:
# 1. 该节点为其父节点的左子节点,则下一节点为其父节点
# 2. 向上遍历后,发现当前节点为其父节点的左子节点,则下一节点为当前节点的父节点
# 3. 向上遍历直到根,没有找到一个节点为其父节点的左子节点,则下一节点为空,即根节点的父节点(None)
return next_node