剑指offer笔记5:二叉树的下一个节点(Python)

剑指offer笔记5:二叉树的下一个节点(P65)

题目:二叉树的下一个节点

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。二叉树节点的定义如下:

class TreeLinkNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
        self.next = None

问题分析

以这个二叉树为例进行分析:
在这里插入图片描述
找出二叉树下一个节点分三种情况:

  1. 该节点有右子树
    如图中的节点 b ,要找出 b 的下一节点。根据中序遍历的顺序,b 的下一节点是 h ,即 b 的右子树中最左边的节点。与 b 类似的节点还有 a 、e 、c 。
  2. 该节点没有右子树,且为其父节点的左子节点
    如图中的节点 d ,要找出 d 的下一节点。根据中序遍历的顺序,d 的下一节点是 b ,即 d 的父节点。与 d 类似的节点还有 h 、f 。
  3. 该节点没有右子树,且为其父节点的右子节点
    如图中的节点 i ,要找出 i 的下一节点。根据中序遍历的顺序,i 的下一节点是 a ,即 i 节点所属的最小左子树的父节点。与 i 类似的节点还有 g 。其中 g 不在左子树里,因此 g 没有下一节点。

总结一下步骤:

  1. 该节点有右子树
    从该节点的右子节点出发一直沿着左指针走,找到其右子树中最左边的节点,即为该节点的下一节点。
  2. 该节点没有右子树,且为其父节点的左子节点。
    通过该节点指向父节点的指针找到其父节点,即为该节点的下一节点。
  3. 该节点没有右子树,且为其父节点的右子节点。
    通过该节点指向父节点的指针一直往上遍历,直到找到某节点为其父节点的左子节点为止,其父节点为该节点的下一节点。

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值