Day12 二叉树遍历

深度优先遍历

给你二叉树的根节点 root ,返回它节点值的 前序 /中序 /后序 遍历。

递归

二叉树的遍历默认是先左后右

cpp 复制代码
    //二叉树遍历函数
    void traverse(TreeNode* root){//从某一节点开始
        if(root==nullptr) return;
        traverse(root->left);//访问该节点的左子节点
        traverse(root->right);//访问该节点的右子节点
    }

不管前序、中序还是后序,二叉树的遍历顺序是一致的,该顺序和前序遍历一致。不同序的区别其实在于何时记录一个节点。

任何节点均会被访问三次

  1. 初次访问该节点,还未访问它的左子节点。
  2. 完成左子节点的访问,回到该节点,即将访问右子节点。
  3. 完成右子节点的访问,回到该节点,并继续向上返回

在以上三个时刻对该节点的值进行返回,就分别对应前序 /中序 /后序

cpp 复制代码
    vector<int> ans;
    void traverse(TreeNode* root){
        if(root==nullptr) return;
        //前序处理时机
        traverse(root->left);
        //中序处理时机
        traverse(root->right);
        //后序处理时机
    }

本题的处理为ans.push_back(root->val);

迭代

用栈实现

前序

每次while循环都会弹出一个node,然后让node->right入栈,再让node->left入栈,此时node->left在栈顶。下一次循环会弹出node->left,如果为nullptr,不会有元素入栈,下一次循环会弹出node->right,也就是中左右的遍历顺序。

cpp 复制代码
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<TreeNode*> st;
        st.push(root);
        TreeNode* top;
        while(!st.empty()){
            top = st.top();
            st.pop();
            if(top){
                if(top->right) st.push(top->right);//右结点先入栈,后出栈
                if(top->left) st.push(top->left);
                ans.push_back(top->val);
            }
        }
        return ans;
    }
};

后序

cpp 复制代码
//待写入

中序

cpp 复制代码
//待写入

统一写法

cpp 复制代码
//待写入

广度优先遍历

即层序遍历

102. 二叉树的层序遍历 - 力扣(LeetCode)

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

  • size记录队列中节点个数,决定本层要弹出几次
  • 每弹出一个节点,都要把左右子节点加入队列(如果存在的话)
  • 当所有节点都被弹出,队列中只剩下被弹出的所有节点的子节点,也就是完整的下一层元素

size可以区分队列内哪些节点属于同一层

cpp 复制代码
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> result;
        queue<TreeNode*> q;
        if(root == nullptr) return result;
        q.push(root);
        int size ;
        TreeNode* temp;
        while(!q.empty()){
            size = q.size();
            vector<int> ans;
            for(int i = 0;i<size;i++){
                temp = q.front();
                q.pop();
                ans.push_back(temp->val);
                if(temp->left) q.push(temp->left);
                if(temp->right) q.push(temp->right);
            }
            result.push_back(ans);
        }
        return result;
    }
};
相关推荐
折哥的程序人生 · 物流技术专研5 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
想吃火锅10057 小时前
【leetcode】14.最长公共前缀js
算法·leetcode·职场和发展
云絮.8 小时前
数据库操作
数据库·mysql·算法·oracle
小林ixn8 小时前
LeetCode 206. 反转链表(迭代 + 递归详解)
算法·leetcode·链表
凡人叶枫8 小时前
Effective C++ 条款17:以独立语句将 newed 对象置入智能指针
java·linux·开发语言·c++·算法
菜鸟‍10 小时前
LeetCode 1 27 和 704 || 两数之和 移除元素 二分查找
算法·leetcode·职场和发展
退休倒计时11 小时前
【每日一题】LeetCode 142. 环形链表 II TypeScript
算法·leetcode·链表·typescript
popcorn_min11 小时前
Digits 手写数字识别:随机森林多分类 + 像素级特征热力图
算法·随机森林·分类
liulilittle12 小时前
拥塞控制:排水终止的两种决策:OR 与 AND
网络·tcp/ip·计算机网络·算法·信息与通信·tcp·通信
weixin_3077791312 小时前
从脚本执行到智能体协作:AI辅助测试能力的范式重构
运维·开发语言·人工智能·算法·测试用例