二叉树的深度遍历

news/2024/7/20 20:53:35 标签: 深度优先, 算法

目录

深度优先遍历:

二叉树节点定义: 

递归法:

前序

中序 

后序

迭代法:

前序

中序

后序

迭代法(统一写法)

前序

中序

后序

广度优先遍历:


二叉树的遍历方法包括两种:深度优先遍历广度优先遍历

下面分别介绍这两种遍历方法的具体实现。

代码随想录 (programmercarl.com)icon-default.png?t=N7T8https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E7%A7%8D%E7%B1%BB


深度优先遍历:

        即先往深走,遇到叶子节点再往回走。又包括前序、中序、后序遍历,可分别由递归法与迭代法实现。(PS:这里的三种顺序指的是中间节点的遍历顺序)

前序遍历:中左右

中序遍历:左中右

后序遍历:左右中

二叉树节点定义:
 

// Definition for a binary tree node.
struct TreeNode {
     int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

递归法:

前序

 // 递归法
class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec){
        if(cur == nullptr) return;
        vec.push_back(cur->val);
        traversal(cur->left, vec);
        traversal(cur->right, vec);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> preVec;
        if(root==nullptr) return preVec;
        traversal(root, preVec);
        return preVec;
    }
};

中序 

 // 递归法
class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec){
        if(cur == nullptr) return;
        traversal(cur->left, vec);
        vec.push_back(cur->val);
        traversal(cur->right, vec);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> mid_vec;
        if(root == nullptr) return mid_vec;
        traversal(root, mid_vec);
        return mid_vec;
    }
};

后序

 // 递归法
class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec){
        if(cur == nullptr) return;
        traversal(cur->left, vec);
        traversal(cur->right, vec);
        vec.push_back(cur->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> post_vec;
        if(root == nullptr) return post_vec;
        traversal(root, post_vec);
        return post_vec;
    }
};

迭代法:

前序

 // 迭代法
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> preVec;
        stack<TreeNode*> preStack;
        if(root==nullptr) return preVec;

        preStack.push(root);
        while(!preStack.empty()){
            TreeNode* cur = preStack.top();
            preStack.pop();
            preVec.push_back(cur->val);     // 前序
            // 中节点的右左入栈,左右出栈
            if(cur->right) preStack.push(cur->right);
            if(cur->left) preStack.push(cur->left);
        }
        return preVec;
    }
};

中序

 // 迭代法
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> mid_vec;
        stack<TreeNode*> mid_stack;
        if(root == nullptr) return mid_vec;
        
        TreeNode* cur = root;
        while(cur || !mid_stack.empty()){
            if(cur){
                mid_stack.push(cur);
                cur = cur->left;
            }
            else{
                cur = mid_stack.top();
                mid_stack.pop();
                mid_vec.push_back(cur->val);    // 中序
                cur = cur->right;
            }
        }

        return mid_vec;
    }
};

后序

 // 迭代法
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> post_vec;
        stack<TreeNode*> post_stack;
        if(root == nullptr) return post_vec;
        post_stack.push(root);

        while(!post_stack.empty()){
            TreeNode* cur = post_stack.top();
            post_stack.pop();
            post_vec.push_back(cur->val);    //前序(后面逆转)
            //左右入栈,右左出栈
            if(cur->left) post_stack.push(cur->left);
            if(cur->right) post_stack.push(cur->right);
        }
        // 中右左->左右中
        reverse(post_vec.begin(),post_vec.end());
        return post_vec;
    }
};

迭代法(统一写法)

前序

 // 迭代法(统一风格)
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> preVec;
        stack<TreeNode*> preStack;
        if(root) preStack.push(root);

        while(!preStack.empty()){
            TreeNode* cur = preStack.top();
            if(cur){    // 入栈标记处理节点
                preStack.pop();
                if(cur->right) preStack.push(cur->right);   //右入栈
                if(cur->left) preStack.push(cur->left);     //左入栈
                preStack.push(cur);                        //中入栈
                preStack.push(nullptr);                    //push空节点,标记处理节点
            }
            else{   // 遇空节点出栈处理
                preStack.pop();
                preVec.push_back(preStack.top()->val);
                preStack.pop();
            }
        }
        return preVec;
    }
};

中序

 // 迭代法
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> mid_vec;
        stack<TreeNode*> mid_stack;
        if(root) mid_stack.push(root);
        
        while(!mid_stack.empty()){
            TreeNode* cur = mid_stack.top();
            if(cur){    // 入栈标记处理节点
                mid_stack.pop();
                if(cur->right) mid_stack.push(cur->right);
                mid_stack.push(cur);
                mid_stack.push(nullptr);
                if(cur->left) mid_stack.push(cur->left);
            }
            else{       // 遇空节点出栈处理
                mid_stack.pop();
                mid_vec.push_back(mid_stack.top()->val);    // 中序
                mid_stack.pop();
            }
        }
        return mid_vec;
    }
};

后序

 // 迭代法(统一风格)
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> post_vec;
        stack<TreeNode*> post_stack;
        if(root) post_stack.push(root);

        while(!post_stack.empty()){
            TreeNode* cur = post_stack.top();
            if(cur){    // 入栈标记处理节点
                post_stack.push(nullptr);                       // 中
                if(cur->right) post_stack.push(cur->right);     // 右
                if(cur->left) post_stack.push(cur->left);       // 左
            }
            else{       // 遇空节点出栈处理
                post_stack.pop();
                post_vec.push_back(post_stack.top()->val);
                post_stack.pop();
            }

        }
        return post_vec;
    }
};

广度优先遍历:

        一层一层的去遍历。
        


http://www.niftyadmin.cn/n/5328876.html

相关文章

【大数据】Flink 详解(八):SQL 篇 Ⅰ

《Flink 详解》系列&#xff08;已完结&#xff09;&#xff0c;共包含以下 10 10 10 篇文章&#xff1a; 【大数据】Flink 详解&#xff08;一&#xff09;&#xff1a;基础篇【大数据】Flink 详解&#xff08;二&#xff09;&#xff1a;核心篇 Ⅰ【大数据】Flink 详解&…

代码随想录算法训练营Day14|二叉树(理论基础、递归遍历、迭代遍历、统一迭代)

文章目录 一、理论基础1. 二叉树的种类2. 二叉搜索树3. 平衡二叉搜索树4. 存储方式5. 二叉树的遍历方式 二、递归遍历1. 递归遍历三要素2. 144.前序遍历3. 145.后序遍历4. 94.中序遍历 三、迭代遍历1. 144.前序遍历2. 145.后序遍历3. 94.中序遍历 四、统一迭代1. 144.前序遍历2…

Ezsql

靶场说明 靶机地址解释&#xff1a; 第一行&#xff1a;目标机器 WEB 服务地址 第二行&#xff1a;目标机器 SSH 地址以及端口 第三行&#xff1a;Check 服务访问地址。 http://99bdd2da-7d5e-4b5c-a7ee-79713b8ecabc.node5.buuoj.cn:8199bdd2da-7d5e-4b5c-a7ee-79713b8ecabc…

【笔记】认识电机

认识电机 电机一些概念永磁同步电机永磁体定子和转子励磁电磁感应定律 AC Optimal Power Flow功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右Smart…

PlatformIO中ESP8266使用GxEPD库和U8G2库驱动 2.9寸黑白墨水屏显示中文

Content 0. 前言1. 安装platformIO环境2. 新建工程3. 添加外部库4. 修改U8g2_for_Adafruit_GFX库5. 代码和烧录 0. 前言 墨水屏是黄鱼淘的&#xff0c;效果还不错。 U8G2库一直编译不进去&#xff0c;显示汉字始终不太美观&#xff0c;个人一直不太喜欢汉字取模的方法&#x…

Could not erase files or folders:

IDEA删除 git 的 localChanges 内的文件时&#xff0c;提示Could not erase files or folders:。 确认下这个文件是否被打开&#xff0c;忘记关闭了&#xff1b;关闭后可以被删除。&#xff08;文件被打开的情况下&#xff0c;用操作系统自带的删除&#xff0c;也无法删除成功…

【论文笔记合集】卷积神经网络之深度可分离卷积(Depthwise Separable Convolution)

本文作者&#xff1a; slience_me 我看的论文地址&#xff1a;MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications 内容 1. 标准卷积 假设输入为DFDFM&#xff0c;输出为输入为DFDFN&#xff0c;卷积核为DKDKM&#xff0c;共有N个卷积核进…

【K8S 】K8S配置资源管理

一、Secret&#xff1a; 1、概念 用来保存密码。token&#xff0c;敏感的K8S资源 这类数据可以直接存放在镜像中&#xff0c;但是放在Secret中可以更方便的控制&#xff0c;减少暴露的风险 Secret&#xff1a;保存加密的信息 2、Secret类型&#xff1a; docker-registry&am…