📜  数据结构 |树遍历 |问题 12(1)

📅  最后修改于: 2023-12-03 14:54:56.353000             🧑  作者: Mango

数据结构 | 树遍历 | 问题 12

简介

树遍历是指按照一定的顺序遍历树中的所有节点。常见的树遍历方式有前序遍历、中序遍历和后序遍历。在程序设计中,树遍历是一项基本的操作,常被应用于树的查找、删除、修改等操作中。

问题描述

给定一棵二叉树,设计算法实现二叉树的前序、中序、后序遍历。要求采用递归、迭代两种方式实现。

分析与解决
递归实现

对于二叉树的遍历,最常见的实现方式是递归。递归的实现方式类似于人类对树的遍历方式,即先遍历左子树,再遍历右子树,并在遍历子树时再分别递归访问子树的左右节点。

以下是二叉树的前序、中序、后序遍历的递归实现方法:

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
        
# 前序遍历
def preorderTraversal(root: TreeNode) -> List[int]:
    res = []
    def dfs(root):
        if root:
            res.append(root.val)
            dfs(root.left)
            dfs(root.right)
    dfs(root)
    return res

# 中序遍历
def inorderTraversal(root: TreeNode) -> List[int]:
    res = []
    def dfs(root):
        if root:
            dfs(root.left)
            res.append(root.val)
            dfs(root.right)
    dfs(root)
    return res

# 后序遍历
def postorderTraversal(root: TreeNode) -> List[int]:
    res = []
    def dfs(root):
        if root:
            dfs(root.left)
            dfs(root.right)
            res.append(root.val)
    dfs(root)
    return res
迭代实现

除了递归实现,还可以采用迭代实现方式。由于采用迭代实现方式时无法使用递归所具备的隐式栈,需要显式地维护一个栈来存储树的节点,避免遗漏。

以下是二叉树的前序、中序、后序遍历的迭代实现方法:

# 前序遍历
def preorderTraversal(root: TreeNode) -> List[int]:
    if not root:
        return []
    res = []
    stack = [root]
    while stack:
        node = stack.pop()
        res.append(node.val)
        if node.right:
            stack.append(node.right)
        if node.left:
            stack.append(node.left)
    return res

# 中序遍历
def inorderTraversal(root: TreeNode) -> List[int]:
    if not root: 
        return []
    res = []
    stack = []
    cur = root
    while cur or stack:
        while cur:
            stack.append(cur)
            cur = cur.left
        node = stack.pop()
        res.append(node.val)
        cur = node.right
    return res

# 后序遍历
def postorderTraversal(root: TreeNode) -> List[int]:
    if not root:
        return []
    res = []
    stack = []
    lastvisited = None
    while root or stack:
        if root:
            stack.append(root)
            root = root.left
        else:
            node = stack[-1]
            if node.right and lastvisited != node.right:
                root = node.right
            else:
                res.append(node.val)
                lastvisited = stack.pop()
    return res
总结

无论是递归实现还是迭代实现,对于二叉树的遍历都是基本操作。采用递归实现时简单明了,易于理解,但当树的深度较大时会增加递归调用栈的负担,可能导致栈溢出。而迭代实现虽然需要显式地维护一个栈,但不用考虑调用栈是否足够的问题,大大提高了程序的鲁棒性。