94.二叉树的中序遍历- 力扣(LeetCode)

题目:

        给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

示例 1:

94.二叉树的中序遍历- 力扣(LeetCode)_第1张图片

输入:root = [1,null,2,3]

输出:[1,3,2]

示例 2:

输入:root = []

输出:[]

示例 3:

输入:root = [1]

输出:[1]

提示:

  • 树中节点数目在范围 [0, 100] 内

  • -100 <= Node.val <= 100

思路如下:

解法一:递归

  • 先遍历左节点就是inorder(root.left)

  • 然后要将左节点值先加入res中,res.append(root.val)

  • 然后去遍历右节点,inorder(root.right)

  • 最后不要忘了递归的终止条件,如果节点为空结束当前递归分支return

解法二:迭代

  • 与前序遍历的遍历过程差不多,只有将节点值存到结果res中的时机不同。

  • 前序遍历因为要先存根节点,所以上来先把根节点值存到res中再去遍历左节点;

  • 但中序遍历要先存左节点,所以是一直遍历左节点直到左节点为空,然后从栈中弹出上一个节点,这个节点将是当前子树的最左节点,将该节点的值存到res中,然后再令root = root.right

具体步骤

1.循环条件是辅助栈stack非空或root非空,因为只要有一个非空就是节点还没遍历完

2.循环体的内容

  • 先将根节点加到stack中,然后一直去遍历左节点一直遍历到空为止;

  • 如果为空了,也就是root是空节点了,说明当前子树的左节点都已经遍历完了,可以开始将左节点值加到res中了,从stack中弹出最近遍历到的节点,将节点值加到res中后让root = root.right

3.最后返回res

题解如下:

解法一:递归

class Solution:
    def inorderTraversal(self, root):
        """
                  :type:  root: TreeNode
                  :rtype: List[int]
        """
        # 将递归函数命名为 inorder
        def inorder(root):        # 递归终止条件:当前节点为空时返回
            if not root:
                return
            inorder(root.left)    # 递归左子树
            ans.append(root.val)  # 处理当前节点(中序位置)
            inorder(root.right)   # 递归右子树
        
        ans = []       # 初始化结果列表
        inorder(root)  # 调用入口同步修改为 inorder
        return ans     # 返回最终结果

解法二:迭代

class Solution:
   def inorderTraversal(self, root):
        """
                  :type:  root: TreeNode
                  :rtype: List[int]
        """
        res, stack = [], []           # 初始化结果列表和辅助栈
        while stack or root:          # 当栈非空或当前节点存在时循环
            if root:                  # 当前节点存在
                stack.append(root)    # 将当前节点压入栈
                root = root.left      # 深入左子树
            else:                     # 当前节点为空(左子树到尽头)
                root = stack.pop()    # 弹出栈顶节点(上一个未处理的父节点)
                res.append(root.val)  # 将节点值加入结果列表(此时左子树已处理完)
                root = root.right     # 转向处理右子树
        return res                    # 返回中序遍历结果
示例流程:

解法一:递归

以二叉树 [1, null, 2, 3] 为例:

   1     
    \      
     2     
    /    
   3
  1. 初始调用 inorder(1)。

  2. 进入 inorder(1),递归调用 inorder(1.left)(即 inorder(None)),直接返回。

  3. 将 1 加入 ans(此时 ans = [1])。

  4. 递归调用 inorder(1.right)(即 inorder(2))。

  5. 进入 inorder(2),递归调用 inorder(2.left)(即 inorder(3))。

  6. 进入 inorder(3),递归调用 inorder(3.left)(即 inorder(None)),返回。

  7. 将 3 加入 ans(此时 ans = [1,3])。

  8. 递归调用 inorder(3.right)(即 inorder(None)),返回。

  9. 返回到 inorder(2),将 2 加入 ans(此时 ans = [1,3,2])。

  10. 递归调用 inorder(2.right)(即 inorder(None)),返回。

  11. 最终返回 ans = [1,3,2]。

解法二:迭代

以二叉树 [1,2,3,4,5] 为例:

      1
     / \
    2   3
   / \
  4   5
  1. 初始状态:root=1,栈为空。

  2. 压入 1 → 压入 2 → 压入 4,此时 root=None。

  3. 弹出 4,加入结果 → 处理右子节点(无)。

  4. 弹出 2,加入结果 → 处理右子节点 5。

  5. 压入 5 → root=None → 弹出 5,加入结果。

  6. 弹出 1,加入结果 → 处理右子节点 3。

  7. 压入 3 → root=None → 弹出 3,加入结果。

你可能感兴趣的:(leetcode,算法,python)