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;
    }
};
相关推荐
加藤不太惠3 小时前
十大排序其六
算法·排序算法
前端小刘哥3 小时前
视频推拉流平台EasyDSS技术特点及多元应用场景剖析
算法
Brianna Home3 小时前
从零到一:用Godot打造2D游戏《丛林探险》
算法·游戏·性能优化·游戏引擎·bug·godot·动画
小欣加油3 小时前
leetcode 143 重排链表
数据结构·c++·算法·leetcode·链表
courniche4 小时前
ECDH、ECDHE、ECDLP、ECDSA傻傻分不清?
算法·密码学
前端小刘哥4 小时前
超低延迟与高并发:视频直播点播平台EasyDSS在游戏直播场景的技术实践
算法
毅炼4 小时前
常见排序算法
java·算法·排序算法
猫梦www4 小时前
力扣21:合并两个有序链表
数据结构·算法·leetcode·链表·golang·力扣
Han.miracle5 小时前
数据结构——排序的学习(一)
java·数据结构·学习·算法·排序算法