代码随想录算法训练营第十一天(二叉树篇)|Leetcode144二叉树的前序遍历,Leetcode145二叉树的后序遍历,Leetcode94二叉树的中序遍历,Leetcode102二叉树的层序遍历

Leetcode 144 二叉树的前序遍历

题目链接: 二叉树的前序遍历
给定一棵二叉树的根节点,返回该二叉树通过前序遍历得到的节点数组

思路: 首先回忆前序遍历。二叉树的前序遍历,即是将二叉树中节点按照 "中左右" 的顺序进行遍历,得到的节点数组即为前序遍历的结果。

考虑以下二叉树:

        1
       / \
      2   3
     / \   \
    4   5   6

其前序遍历得到的结果为 [1,2,3,4,5,6]
首先从根节点 1 开始,随后处理它的左子节点 2,接着是它的右子节点 3。接着是 2 的左子节点 42 的右子节点 5,最后是 3 的右子节点 6。完成前序遍历的过程

为了彻底理解前序遍历的实现,以下将给出递归法,迭代法的二叉树前序遍历实现。

# 递归法
class Solution:
    def traverse(self, cur: Optional[TreeNode], result: List[int]) -> None:
        # 递归终止条件: 当前节点为空
        if cur is None:
            return

        # 分别处理中-左-右节点
        result.append(cur.val)
        self.traverse(cur.left, result)
        self.traverse(cur.right , result)

    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        self.traverse(root, result)
        return result
# 迭代法
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        myStack = []  # 通过将节点按照一定的顺序压入栈,并处理栈顶节点,实现前序遍历

        if root is None:
            return result

        myStack.append(root)

        # 只要栈中还存在节点元素,就继续处理
        while myStack:
            # 栈顶元素即为当前正在处理的节点
            cur = myStack.pop()
            result.append(cur.val)

            # 根据栈后入先出的特性,先将当前节点的右孩子压入栈中,然后是左孩子。这样左孩子先出栈。
            if cur.right is not None:
                myStack.append(cur.right)
            if cur.left is not None:
                myStack.append(cur.left)

        return result

Leetcode 145 二叉树的后序遍历

题目链接: 二叉树的后序遍历

给定一棵二叉树的根节点,返回二叉树经过后序遍历得到的节点数组

思路: 后序遍历,即是将二叉树中节点按照 "左右中" 的顺序进行遍历,得到的节点数组即为后序遍历的结果。

考虑以下二叉树:

        1
       / \
      2   3
     / \   \
    4   5   6

其后序遍历得到的结果为 [4,5,2,6,3,1]。首先看二叉树的左子树,左节点为 4,右节点为 5,中间节点为 2;然后看二叉树的右子树,右节点为 6,中间节点为 3;最后是二叉树的根节点 1

此处同样给出递归法,迭代法的实现。除此之外,还给出利用标志位标记节点的迭代法的实现。

具体代码实现

# 递归法
class Solution:
    def traverse(self, cur: Optional[TreeNode], result: List[int]) -> None:
        # 递归终止条件: 当前节点为空
        if cur is None:
            return

        # 按照左右中的顺序遍历节点
        self.traverse(cur.left, result)
        self.traverse(cur.right, result)
        result.append(cur.val)

    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        self.traverse(root, result)
        return result
# 迭代法
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        myStack = []  # 将节点压入栈中

        if root is None:
            return result

        myStack.append(root)

        # 此处压栈时按照中右左的顺序处理节点,最后将得到的结果进行反转,即得到按照左右中顺序处理的后序遍历的结果
        while myStack:
            cur = myStack.pop()
            result.append(cur.val)

            if cur.left is not None:
                myStack.append(cur.left)
            if cur.right is not None:
                myStack.append(cur.right)

        return result[::-1]

我们利用迭代法实现二叉树遍历时,最大的难题在于,如何处理好当前遍历的节点与实际应当处理的节点的不同。之前我们通过压栈解决了这一问题,但是这将导致前中后序二叉树遍历的代码写法不一致,难以记忆。

因此,我们可以利用标志位标记节点,仅收获标记位符合要求的节点的值,这样统一了代码写法,更容易理解

# 利用标志位标记节点的迭代法实现
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        myStack = []

        if root is not None:
            myStack.append([root, False])

        while myStack:
            node, visited = myStack.pop()

            # 仅将标志位为True的节点值加入到结果中
            if visited:
                result.append(node.val)
                continue

            # 遍历完中间节点,将中间节点的标志位设置为True,供后续取用
            myStack.append([node, True])

            # 将右子节点,左子节点压入栈中
            if node.right is not None:
                myStack.append([node.right, False])

            if node.left is not None:
                myStack.append([node.left, False])

        return result

Leetcode 94 二叉树的中序遍历

题目链接: 二叉树的中序遍历

给定一棵二叉树的根节点,返回该二叉树通过中序遍历得到的节点数组

思路: 中序遍历,即按照 "左中右" 的顺序遍历二叉树节点。

考虑以下二叉树:

        1
       / \
      2   3
     / \   \
    4   5   6

其中序遍历得到的结果为 [4,2,5,1,3,6]。首先是左子树的左节点 4,左子树的中间节点 2,左子树的右节点 5;然后是根节点 1,然后是右子树的中间节点 3,右子树的右节点 6

以下同样给出递归法,迭代法,以及带标志位的迭代法

具体代码实现

# 递归法
class Solution:
    def traverse(self, cur: Optional[TreeNode], result: List[int]) -> None:
        if cur is None:
            return

        self.traverse(cur.left, result)
        result.append(cur.val)
        self.traverse(cur.right, result)

    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        self.traverse(root, result)
        return result
# 迭代法
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        myStack = []

        cur = root

        # 深度优先搜索
        while cur is not None or myStack:
            # 将中间节点入栈供后续取用,寻找最深的左子节点
            if cur is not None:
                myStack.append(cur)
                cur = cur.left
            else:
                # 处理完中间节点后,再处理右节点
                cur = myStack.pop()
                result.append(cur.val)
                cur = cur.right

        return result
# 带标志位的迭代法
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        myStack = []

        if root is not None:
            myStack.append([root, False])

        while myStack:
            node, visited = myStack.pop()

            # 当前节点先前已经遍历过,收获其结果即可
            if visited:
                result.append(node.val)
                continue

            # 右节点压栈
            if node.right is not None:
                myStack.append([node.right, False])

            # 已经遍历过中间节点了,将其标志位改为True,下次遇到时收获其值
            myStack.append([node, True])

            # 左节点压栈
            if node.left is not None:
                myStack.append([node.left, False])

        return result

Leetcode 102 二叉树的层序遍历

题目链接: 二叉树的层序遍历

给定一棵二叉树的根节点,返回该二叉树中通过层序遍历得到的节点数组

思路: 层序遍历,即按照 "层层深入" 的顺序遍历二叉树节点。只有当遍历完当前层以后,才会遍历下一层,直至遍历完二叉树中的所有层。

考虑以下二叉树:

        1
       / \
      2   3
     / \   \
    4   5   6

其层序遍历得到的结果为 [[1],[2,3],[4,5,6]]

我们可以使用队列解决这一问题: 当处理当前节点时,将当前节点的孩子节点放入队列中,直到处理完当前层级的节点后,将当前层级的一维节点数组插入到二维结果数组中

具体代码实现:

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        from collections import deque
        result = []
        myQueue = deque()

        if root is not None:
            myQueue.append(root)

        while myQueue:
            # 统计当前层级的节点数量
            size = len(myQueue)
            levelResult = []

            for _ in range(size):
                node = myQueue.popleft()  # 取出当前需要处理的节点
                levelResult.append(node.val)

                # 若孩子节点存在,将其插入到队列中
                if node.left:
                    myQueue.append(node.left)

                if node.right:
                    myQueue.append(node.right)

            result.append(levelResult)

        return result
posted @ 2025-08-20 16:15  雪痕春风天音九重色  阅读(9)  评论(0)    收藏  举报