LeetCode - 144. 二叉树的前序遍历

目录

题目

什么是前序遍历

递归的写法

非递归的写法

思路

实现


题目

144. 二叉树的前序遍历 - 力扣(LeetCode)

什么是前序遍历

前序遍历(Preorder Traversal)是一种遍历树形结构的方法,特别是在二叉树中常用。它的遍历顺序为:

  • 先访问根节点
  • 然后递归地前序遍历左子树
  • 最后递归地前序遍历右子树

这种遍历方式也称为"深度优先遍历"(DFS)的一种形式。

示例

对于以下二叉树:

复制代码
    A
   / \
  B   C
 / \   \
D   E   F

前序遍历的结果是:A → B → D → E → C → F

递归的写法

cpp 复制代码
vector<int> preorderTraversal(TreeNode* root) {
    vector<int> result;
    preorder(root, result);
    return result;
}

void preorder(TreeNode* node, vector<int>& result) {
    if (node == nullptr) {
        return;
    }
    
    // 前序遍历顺序:根 -> 左 -> 右
    result.push_back(node->val);  // 访问根节点
    preorder(node->left, result);  // 递归访问左子树
    preorder(node->right, result);  // 递归访问右子树
}

非递归的写法

思路

初始化:

  • 创建一个空的结果数组 result 用于存储遍历结果
  • 创建一个栈 stack 用于存储待访问的节点
  • 检查根节点是否为空,如果为空直接返回空结果

算法流程:

  • 将根节点压入栈中
  • 当栈不为空时,重复以下步骤:

弹出栈顶节点 current

将 current 的值加入结果数组(访问当前节点)

关键点:先将右子节点压栈,再将左子节点压栈

  • 这是因为栈是后进先出(LIFO)的数据结构
  • 我们希望左子节点先于右子节点被处理,所以右子节点要先入栈

继续循环,直到栈为空

为什么这样工作:

  • 每次我们弹出一个节点,立即访问它(符合前序的"先访问根"原则)
  • 然后将其子节点以"右-左"顺序压栈,这样出栈顺序就是"左-右"
  • 这保证了对于每个子树,我们都是按照"根-左-右"的顺序访问

复杂度分析:

  • 时间复杂度:O(n),其中 n 是树中的节点数,每个节点被访问一次
  • 空间复杂度:O(h),其中 h 是树的高度,最坏情况下为 O(n)(树完全不平衡)

实现

cpp 复制代码
vector<int> preorderTraversal(TreeNode* root) {
    vector<int> result;
    if (root == nullptr) {
        return result;
    }
    
    stack<TreeNode*> st;
    st.push(root);
    
    while (!st.empty()) {
        // 弹出栈顶节点并访问
        TreeNode* node = st.top();
        st.pop();
        result.push_back(node->val);
        
        // 注意:先压入右子节点,再压入左子节点
        // 这样出栈时才会先处理左子节点(栈是后进先出)
        if (node->right) {
            st.push(node->right);
        }
        if (node->left) {
            st.push(node->left);
        }
    }
    
    return result;
}
相关推荐
闻缺陷则喜何志丹6 小时前
【SOSDP模板 容斥原理 逆向思考】3757. 有效子序列的数量|分数未知
c++·算法·力扣·容斥原理·sosdp·逆向思考
第二只羽毛6 小时前
遵守robots协议的友好爬虫
大数据·爬虫·python·算法·网络爬虫
艾斯比的日常6 小时前
Java 三色标记算法:并发垃圾回收的核心技术解析
java·开发语言·算法
CoovallyAIHub7 小时前
抛弃LLM!MIT用纯视觉方法破解ARC难题,性能接近人类水平
深度学习·算法·计算机视觉
程序猿编码7 小时前
PRINCE算法的密码生成器:原理与设计思路(C/C++代码实现)
c语言·网络·c++·算法·安全·prince
高洁017 小时前
具身智能-视觉语言导航(VLN)
深度学习·算法·aigc·transformer·知识图谱
Hacker_Oldv7 小时前
API 自动化测试难点总结与分享
自动化测试·软件测试·职场和发展
Croa-vo7 小时前
TikTok 数据工程师三轮 VO 超详细面经:技术深挖 + 建模推导 + 压力测试全记录
javascript·数据结构·经验分享·算法·面试
蘑菇小白7 小时前
时间复杂度
数据结构·算法
czlczl200209257 小时前
算法:组合问题
算法·leetcode·职场和发展