【树-简单】144. 二叉树的前序遍历(三种方法遍历递归+迭代+Mirrors,需要复习)

本文介绍二叉树的前序遍历算法,并提供递归及迭代实现方式。包括基本概念、示例解析及不同遍历方法的代码示例。

题目
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
【示例 1】
输入:root = [1,null,2,3]
输出:[1,2,3]
【示例 2】
输入:root = []
输出:[]
【示例 3】
输入:root = [1]
输出:[1]
【示例 4】
输入:root = [1,2]
输出:[1,2]
【示例 5】
输入:root = [1,null,2]
输出:[1,2]
【提示】

树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100

进阶:递归算法很简单,你可以通过迭代算法完成吗?
【代码】
在这里插入图片描述

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def visit(self,root):
        if not root:
            return
        self.ans.append(root.val)
        self.visit(root.left)
        self.visit(root.right)

    def preorderTraversal(self, root: TreeNode) -> List[int]:
        self.ans=[]
        self.visit(root)
        return self.ans

【进阶1】
在这里插入图片描述

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        res = list()
        if not root:
            return res
        
        stack = []
        node = root
        while stack or node:
            while node:
                res.append(node.val)
                stack.append(node)
                node = node.left
            node = stack.pop()
            node = node.right
        return res

【进阶2】
在这里插入图片描述

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        ans = []
        if not root:
            return ans
        stack = [root]
        while stack:
            node = stack.pop()
            ans.append(node.val)
            print(ans)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return ans

【进阶3-Mirrors遍历】
在这里插入图片描述

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        res = list()
        if not root:
            return res
        
        p1 = root
        while p1:
            p2 = p1.left
            if p2:
                while p2.right and p2.right != p1:
                    p2 = p2.right
                if not p2.right:
                    res.append(p1.val)
                    p2.right = p1
                    p1 = p1.left
                    continue
                else:
                    p2.right = None
            else:
                res.append(p1.val)
            p1 = p1.right
        
        return res

二叉树递归遍历过程中,前序、中序和后序遍历的工作栈状态变化反映了函数调用栈中递归调用的顺序和状态。递归遍历本质上是利用程序运行时的调用栈来实现栈帧的管理。以下是对前序、中序和后序遍历递归实现过程中工作栈状态变化的详细分析。 ### 前序遍历中的工作栈状态变化 前序遍历递归实现中,访问根节点的操作发生在递归调用左子和右子之前。因此,工作栈中会依次压入根节点的调用帧,直到遇到空节点。例如,在遍历左子时,每进入一个节点,该节点的调用帧被压入栈中,直到左子为空。随后,栈顶的调用帧被弹出,并继续处理右子。这一过程会持续到所有节点被访问完毕。 ### 中序遍历中的工作栈状态变化 中序遍历递归实现中,访问根节点的操作发生在递归调用左子之后、右子之前。因此,工作栈的状态变化表现为先将左子的所有节点的调用帧依次压入栈中,直到最左下角的节点。此时,栈顶的调用帧被弹出,访问该节点,然后处理右子。这一过程确保了左子被完全处理后,才访问根节点,再处理右子。 ### 后序遍历中的工作栈状态变化 后序遍历递归实现中,访问根节点的操作发生在递归调用左子和右子之后。因此,工作栈的状态变化表现为先将左子的所有节点的调用帧依次压入栈中,直到遇到空节点。随后,栈顶的调用帧被弹出并处理右子。在右子处理完成后,根节点的调用帧才会被弹出,并访问根节点。这一过程确保了左子和右子都被完全处理后,才访问根节点。 ### 三种遍历方式的对比 - **前序遍历**:根节点的访问操作在递归调用左右子之前,因此工作栈中根节点的调用帧会被优先压入栈中。 - **中序遍历**:根节点的访问操作在左子处理完成后进行,因此工作栈中左子的调用帧会被优先压入栈中,而根节点的调用帧在栈顶等待访问。 - **后序遍历**:根节点的访问操作在递归调用左右子之后,因此工作栈中左右子的调用帧会被优先压入栈中,而根节点的调用帧在栈顶等待访问。 ### 示例代码 以下为前序、中序和后序遍历递归实现代码,展示了递归调用栈的管理方式: ```c // 前序遍历 void PreOrder(BiTNode *T) { if (T != NULL) { visit(T); // 访问根节点 PreOrder(T->lChild); // 递归遍历左子 PreOrder(T->rChild); // 递归遍历右子 } } // 中序遍历 void InOrder(BiTNode *T) { if (T != NULL) { InOrder(T->lChild); // 递归遍历左子 visit(T); // 访问根节点 InOrder(T->rChild); // 递归遍历右子 } } // 后序遍历 void PostOrder(BiTNode *T) { if (T != NULL) { PostOrder(T->lChild); // 递归遍历左子 PostOrder(T->rChild); // 递归遍历右子 visit(T); // 访问根节点 } } ``` ### 工作栈状态变化的总结 - **前序遍历**:根节点的调用帧优先被压入栈中,随后处理左子和右子- **中序遍历**:左子的调用帧优先被压入栈中,随后处理根节点和右子- **后序遍历**:左右子的调用帧优先被压入栈中,随后处理根节点。 在递归实现中,工作栈的状态变化直接反映了递归调用的顺序和逻辑,从而确保遍历结果的正确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值