题目:
设计一个算法,找出二叉搜索树中指定节点(记为p)的“下一个”节点(也即中序后继)。
如果指定节点没有对应的“下一个”节点,则返回null
。
思路:
第一种解法可以适用于非搜索树的情况:当p是父结点的左孩子且没有右孩子时,它的中序后继就是父结点;否则,它的中序后继是p的右孩子的最左结点。所以,我们需要的是维护中序遍历中上一个访问的结点,以及当前结点,如果上一个访问的结点是p,那么就输出当前节点。中序遍历代码见二叉树-7.5 二叉树的打印_Iamlzm的博客-优快云博客
代码:
class Solution(object):
def inorderSuccessor(self, root, p):
"""
:type root: TreeNode
:type p: TreeNode
:rtype: TreeNode
"""
cur, pre = root, None
st = []
while cur or st:
while cur:
st.append(cur)
cur = cur.left
cur = st.pop()
if pre == p:
return cur
pre = cur
cur = cur.right
return None
第二种解法利用了二叉搜索树的特点:因为二叉搜索树的中序序列是有序的(该题中为升序),如果一个结点有中序后继,那么它在中序序列中一定不是最大的。
如果p有右孩子:那么它的中序后继就是右子树的最左结点。
如果p没有右孩子:对于任意一个结点n,如果它的值比p值大,说明p在n左边,应该到n的左子树中去找,由于p可能是n的左子树中的最右结点,p可能就是n的中序后继,所以需要记录一下n;如果n的值比p小,应该到n的右边去寻找,此时n绝不可能是p的中序后继。
代码:
class Solution(object):
def inorderSuccessor(self, root, p):
"""
:type root: TreeNode
:type p: TreeNode
:rtype: TreeNode
"""
suc = None
if p.right:
suc = p.right
while suc.left:
suc = suc.left
return suc
while root:
if root == p:
return suc
if root.val > p.val:
suc = root
root = root.left
else:
root = root.right
return None