代码随想录算法训练营第14天 | 二叉树的递归遍历和迭代遍历

一:基础知识

二叉树主要有两种遍历方式:

深度优先遍历:先往深走,遇到叶子节点再往回走。

广度优先遍历:一层一层的去遍历。

深度优先遍历:前中后序遍历,使用栈的结构。

前序遍历(递归法,迭代法)

中序遍历(递归法,迭代法)

后序遍历(递归法,迭代法)

广度优先遍历:层序遍历,使用队列的结构。

层次遍历(迭代法)

中间节点的顺序就是所谓的遍历方式。

前中后序遍历的区别:看中间节点的顺序,前序遍历就是先遍历中间节点,后序遍历就是最后才遍历中间节点。

前序遍历:中左右

中序遍历:左中右

后序遍历:左右中

二:递归遍历

前中后序遍历的递归写法比较简单,看代码理解一下思路即可。

题目链接:144. 二叉树的前序遍历 - 力扣(LeetCode)

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        
        left = self.preorderTraversal(root.left)
        right = self.preorderTraversal(root.right)

        return [root.val] + left + right

题目链接:94. 二叉树的中序遍历 - 力扣(LeetCode)

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        left = self.inorderTraversal(root.left)
        right = self.inorderTraversal(root.right)

        return left + [root.val] + right

题目链接:145. 二叉树的后序遍历 - 力扣(LeetCode)

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = 0
        self.left = left
        self.right = right

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        left = self.postorderTraversal(root.left)
        right = self.postorderTraversal(root.right)

        return left + right + [root.val]

三:迭代遍历

前序遍历:

前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。

为什么要先加入 右孩子,再加入左孩子呢? 因为这样出栈的时候才是中左右的顺序。

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        
        stack = [root]
        result = []
        while stack:
            # 先处理中间节点
            node = stack.pop()
            result.append(node.val)
            # 为了左孩子先出栈先处理,就得先把右孩子入栈
            if node.right:
                stack.append(node.right)
            # 左孩子后入栈
            if node.left:
                stack.append(node.left)
                
        return result

中序遍历:

中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的。

那么在使用迭代法写中序遍历,就需要借用指针(定义一个cur)的遍历来帮助访问节点,栈则用来处理节点上的元素。

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        stack = []
        cur = root
        result = []
        while cur or stack:
            # 一直迭代访问到最底层的左子树节点
            if cur:
                stack.append(cur)
                cur = cur.left
            # 最底层的左子树节点访问完毕再开始处理栈顶元素
            else:
                cur = stack.pop()
                result.append(node.val)
                # 再处理栈顶元素的右节点
                cur = cur.right

        return result

后序遍历:

后序遍历,先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了。

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = 0
        self.left = left
        self.right = right

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []

        stack = [root]
        result = []
        while stack:
            # 先处理中间节点
            node = stack.pop()
            result.append(node.val)
            # 为了先处理右孩子,所以先把左孩子入栈
            if node.left:
                stack.append(node.left)
            # 右孩子后入栈
            if node.right:
                stack.append(node.right)
        # 得到 中右左,反转后得到左右中,也就是后序遍历的结果
        return result[::-1]

你可能感兴趣的:(数据结构和算法,算法,数据结构)