二叉树的迭代遍历 前序 中序 后序 模板

2023-05-16

作为个人学习笔记,原出处讲的很清楚:代码随想录

非标记法

使用非标记法写的话,中序的代码风格和前后序完全不同

中序:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) { // 指针来访问节点,访问到最底层
                st.push(cur); // 将访问的节点放进栈
                cur = cur->left;                // 左
            } else {
                cur = st.top(); // 从栈里弹出的数据,就是要处理的数据(放进result数组里的数据)
                st.pop();
                result.push_back(cur->val);     // 中
                cur = cur->right;               // 右
            }
        }
        return result;
    }
};

前序:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> result;
        if (root == NULL) return result;
        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;
    }
};

后序

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> result;
        if (root == NULL) return result;
        st.push(root);
        while (!st.empty()) {
            TreeNode* node = st.top();
            st.pop();
            result.push_back(node->val);
            if (node->left) st.push(node->left); // 相对于前序遍历,这更改一下入栈顺序 (空节点不入栈)
            if (node->right) st.push(node->right); // 空节点不入栈
        }
        reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序了
        return result;
    }
};

标记法

使用标记法,可以统一三种遍历

我们以中序遍历为例,在二叉树中序遍历使用栈的话,无法同时解决访问节点(遍历节点)和处理节点(将元素放进结果集)不一致的情况。

那我们就将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记。

如何标记呢,就是要处理的节点放入栈之后,紧接着放入一个空指针作为标记。 这种方法也可以叫做标记法。

中序:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> st;
        if (root != NULL) st.push(root);
        while (!st.empty()) {
            TreeNode* node = st.top();
            if (node != NULL) {
                st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
                if (node->right) st.push(node->right);  // 添加右节点(空节点不入栈)

                st.push(node);                          // 添加中节点
                st.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。

                if (node->left) st.push(node->left);    // 添加左节点(空节点不入栈)
            } else { // 只有遇到空节点的时候,才将下一个节点放进结果集
                st.pop();           // 将空节点弹出
                node = st.top();    // 重新取出栈中元素
                st.pop();
                result.push_back(node->val); // 加入到结果集
            }
        }
        return result;
    }
};

前序:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> st;
        if (root != NULL) st.push(root);
        while (!st.empty()) {
            TreeNode* node = st.top();
            if (node != NULL) {
                st.pop();
                if (node->right) st.push(node->right);  // 右
                if (node->left) st.push(node->left);    // 左
                st.push(node);                          // 中
                st.push(NULL);
            } else {
                st.pop();
                node = st.top();
                st.pop();
                result.push_back(node->val);
            }
        }
        return result;
    }
};

后序:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> st;
        if (root != NULL) st.push(root);
        while (!st.empty()) {
            TreeNode* node = st.top();
            if (node != NULL) {
                st.pop();
                if (node->right) st.push(node->right);  // 右
                if (node->left) st.push(node->left);    // 左
                st.push(node);                          // 中
                st.push(NULL);
            } else {
                st.pop();
                node = st.top();
                st.pop();
                result.push_back(node->val);
            }
        }
        return result;
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二叉树的迭代遍历 前序 中序 后序 模板 的相关文章

  • layui date控件的使用

    最近项目多用layui xff0c 就总结一下 span class token tag span class token tag span class token punctuation lt span div span span cla
  • putty超时解决方案

    putty连续3分钟左右没有输入 就自动断开 然后必须重新登陆 很麻烦 在网上查了很多资料 发现原因有多种 环境变量TMOUT引起 ClientAliveCountMax和ClientAliveInterval设置问题或者甚至是防火墙的设置
  • 最好的黑客网站

    全国最早最大的黑客网站 黑客基地 xff1a http vip hackbase com 学黑客必去的网站 黑客基地 xff1a http www hackbase com 新手学黑客快速入门的好地方 xff1a http vip hack
  • mysql-connector-java-5.1.40-bin.jar包

    mysql connector java 5 1 40 bin jar 链接 xff1a https pan baidu com s 1G7 FsxkEJfZ4Cy6R s5j g 提取码 xff1a 5r5o
  • 利用spm12将dicom医学图像格式转成NII格式

    废话不多说 xff0c 直接上干货 xff0c 一 首先下载spm12 国外的下载源 xff0c 比较慢 xff0c 这里有百度网盘 xff0c 需要的直接下载 xff1a 链接 xff1a https pan baidu com s 1Z
  • securityCRT ssh远程开启mysql,断开连接后,mysql服务就停止服务

    问题描述 xff1a ssh远程连接服务器 xff0c 在服务器中开启mysql服务 xff0c 在正常断开ssh 连接后 xff0c 重新连接口查看mysql的状态发现 xff0c mysql的状态 xff1a 重新启动mysql xff
  • py基础之掷骰子游戏的实现

    掷骰子游戏 xff08 循环的使用及掌握 xff09 0 两个骰子都是1 6 1 玩游戏要有金币 xff0c 没有金币不能玩游戏 2 玩一局游戏赠金币一枚 xff0c 充值获得金币 3 充值为10元的倍数 xff0c 10元 20个金币 x
  • centOS 不能上外网怎么下载依赖 (通过挂载镜像)

    问题 我们在服务器上部署系统环境的时候 xff0c 常常会遇到找不到该命令 bash span class token operator span span class token punctuation span span class t
  • linux 搭建FTP服务器

    linux 搭建FTP服务器 网上对于ftp搭建有很多 xff0c 但是说的比较的麻烦 xff0c 而且十分容易出错 xff0c 并且在创建完成后存在一些配置的注意事项 废话不多说 xff0c 现在开始 1 安装 vsftpd 安装FTP服
  • 提取论文中公式神奇(写论文的福音)

    写论文还在愁怎么写复杂的公式吗 xff0c 想引用其他的论文的公式 xff0c 发现都是这样的 P X i
  • java中list.add添加元素覆盖之前的问题

    1 在码代码时 xff0c 发现一个问题 xff1a 使用 list lt object gt list 61 new Arraylist lt object gt list add object xff1b 出现之前添加的元素被最后的元素
  • 线性最优解java实现+Cplex java调用

    一 xff1a cplex的使用 xff1a 1 1 导入cplex jar 包的地址 xff1a https pan baidu com s 1Q0Bv24EQdelV2rY IrLoZQ 提取码 xff1a xn14 1 2 将cple
  • KNN算法(K临近算法)及使用KNN算法实现手写数字0-9识别

    首先感谢博主倔强的小彬雅 xff0c 本文使用的素材及部分代码来源其博文机器学习入门 用KNN实现手写数字图片识别 xff08 包含自己图片转化 xff09 xff0c 需要下载素材的可以到其博文最后进行下载 关于KNN算法 knn算法也叫
  • 如何学习开源飞控

    前言 有一段时间没有更新文章了 新的一年新气象 xff0c 因此还是要抽出时间 xff0c 写点总结与思考 xff0c 对自己的成长也是很有帮助 今天主要想聊一下开源飞控的学习 本人在5年前 xff0c 在知乎下写过一篇回答 xff0c 如
  • 控制系统的观测器基础知识

    1 为什么需要用到观测器 控制原理中的系统框图 xff0c 往往都是假设反馈状态为理想值 但在工程实践中 xff0c 这个是做不到的 一般我们采用传感器测量控制的反馈状态 xff0c 而传感器的测量值 xff0c 存在几个问题 xff1a
  • 浅谈飞控的软件设计

    写在前面 开这个专栏的目的主要是深感自己对飞控软件 算法的知识点过于杂乱 xff0c 很久没有进行系统的总结了 xff0c 因此决定写几篇文章记录一些飞控开发过程的知识点 主要是针对一些软件 算法部分进行讨论 xff0c 如内容有错误 xf
  • 飞控IMU数据进阶处理(FFT,滤波器)

    前面的文章 xff08 知乎专栏 https zhuanlan zhihu com c 60591778 xff09 曾简单讲过IMU数据 xff08 陀螺仪 加速度数据 xff09 的校准以及一阶低通滤波 本文在此基础上更进一步讲一下数据
  • (5)py接口自动化之配置文件&数据库连接详解

    目录 一 配置文件 ini amp yaml 1 作用 2 ini A 语法 B 特点 C 操作方法 3 yaml A 安装第三方库 B 支持的数据类型 C 特性 D 语法 E 数据读取 二 数据库连接与pytho配置文件 1 安装数据库
  • 再谈IMU数据处理(滤波器)

    本文开始前 xff0c 先回答一个问题 上一篇文章最后提到了卡尔曼滤波器用来做一维数据的数字滤波处理 xff0c 最终的实验结果说 xff1a 该模型下的卡尔曼滤波处理与二阶IIR低通滤波处理效果几乎一致 有网友指出是错误的 xff0c 卡

随机推荐