目录

题目

解答

递归的方法

迭代的方法-前序遍历

迭代的方法-中序遍历

迭代的方法-后序遍历

最优解之一


题目

144. 二叉树的前序遍历

给定一个二叉树,返回它的 前序 遍历。

  • 深度优先搜索(DFS):

    • 在这个策略中,我们采用深度作为优先级,以便从跟开始一直到达某个确定的叶子,然后再返回根到达另一个分支。
    • 深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为前序遍历,中序遍历和后序遍历

示例:

输入: [1,null,2,3]  1\2/3 输出: [1,2,3]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

解答

递归的方法

//树的结构
struct TreeNode
{int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> res;recurse(root, res);return res;}void recurse(TreeNode* root, vector<int> & res) {if(root == nullptr) { //返回条件return;}//单层逻辑res.push_back(root->val);  //行1recurse(root->left, res);  //行2recurse(root->right, res); //行3}
};//中序遍历: 行2 行1 行3
//后续遍历: 行2 行3 行1

时间复杂度:O(n),n是结点个数,因为每个节点都被访问至少一次。

空间复杂度:O(n),因为使用一个数组存储遍历结果。

递归思想使用的是系统提供的栈,进行迭代。跟如下的迭代方式一致。

迭代的方法-前序遍历

方法1: 一层while

先根节点入栈, 在while循环中, 弹出栈顶元素(根), 然后先右节点入栈,再左节点入栈即可.因为在while循环中弹出的是栈顶元素, 所以,上述前序遍历是, 先右节点入栈.

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> res;if(root == nullptr) return res;stack<TreeNode*> st;st.push(root); //注意: 先把根节点《放入栈》, 然后开始表演while (!st.empty()) {TreeNode * cur = st.top();//《取出》st.pop();res.push_back(cur->val); //行1: 根if(cur->right) st.push(cur->right); //行2 前序: 因为是栈,所以先右节点入栈if(cur->left)  st.push(cur->left);  //行3: 前序: 再左节点入栈}return res;}
};//后续遍历:
//  则是颠倒行2和行3, 得到 根右左 的结果,
//  然后颠倒res结果即可:reverse(res.begin(), res.end());

方法2:二层while

使用栈的方式,存储每一个“根节点”,依次出栈入栈。时间复杂度和空间复杂度都是O(n)。

vector<int> preorderTraversal(TreeNode* root)
{vector<int> result;stack<TreeNode*> stk;TreeNode* tmp = root;  //使用temp临时节点作为遍历对象while(tmp != NULL || !stk.empty()){while (tmp !=NULL) //只要有左子节点,就一直向左访问,同时将每一级的根节点存入栈中{result.push_back(tmp->val); //这行代码在前(相对于left right行),前序遍历stk.push(tmp);tmp = tmp->left;}//左节点访问完成后,通过弹出每一级的根节点,开始访问其右子节点  tmp = stk.top();stk.pop();tmp = tmp->right;}return result;
}

迭代的方法-中序遍历

方法1:一层while

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> res;TreeNode* cur = root; //注意:定义临时节点stack<TreeNode*> st;while (cur != nullptr || !st.empty()) {if (cur != nullptr) {st.push(cur);    //注意:这里区分:“访问节点” 和 “处理节点” 两个概念cur = cur->left; //注意:一直遍历访问左节点,直到为空, //因为左先入栈,然后在后面当左没有时,处理节点,最后右节点入栈,//所以是 左根右,实现了中序} else {cur = st.top();st.pop();res.push_back(cur->val);  // 处理节点cur = cur->right;   //}}return res;}
};

方法2:两层while, 其实和上面是一样的, 只不过分成两个while实现的

vector<int> inorderTraversal(TreeNode* root)
{vector<int> res;stack<TreeNode*> st;TreeNode* cur = root;while (cur || st.size()) {while(cur) {st.push(cur);cur= cur->left;}cur= st.top();st.pop();res.push_back(cur->val); //这行代码在中间(相对于left right行),中序遍历cur= cur->right;}return res;
}

迭代的方法-后序遍历

将前序遍历的模型,进行修改,使其成根右左,再最后加上reverse进行反转,得到左右根,即使后序遍历

vector<int> postorderTraversal(TreeNode* root) {vector<int> res;stack<TreeNode*> stk;TreeNode* tmp= root;while(tmp || stk.size()) {while(tmp) {stk.push(tmp);res.push_back(tmp->val); // 根tmp= tmp->right;         // 右}tmp= stk.top();stk.pop();tmp= tmp->left;              // 左}reverse(res.begin(), res.end()); // 颠倒下return res;
}

最优解之一

HERETO : 莫里斯遍历 力扣

算法笔记_面试题_4.树的遍历(前序/中序/后续遍历)相关推荐

  1. 【笔记】二叉树递归算法和非递归算法的实现 先序/中序/后续遍历 打印结点以及顺序数 构造二叉树

    递归先序遍历和中序遍历 先序: void preorder(bnode *t){if(t!=NULL){ visit(t);preorder(t->lchild); preorder(t-> ...

  2. 二叉树前序中序后续线索树_后序线索二叉树怎么画 线索二叉树基本操作详解 - 办公软件 - 服务器之家...

    后序线索二叉树怎么画 线索二叉树基本操作详解 发布时间:2017-05-23 来源:服务器之家 遍历二叉树是以一定规则将二叉树中结点排列成一个线性序列,得到二叉树中结点的先序,中序或后序序列.这实际上 ...

  3. 二叉树前序中序后续线索树_二叉树的先序,中序,后序遍历以及线索二叉树的遍历...

    二叉树的先序,中序,后序遍历以及线索二叉树的遍历 (2008-05-04 17:52:49) 标签: 杂谈 C++ 二叉树的先序,中序,后序遍历以及线索二叉树的遍历 头文件 //*********** ...

  4. c++ 删除二叉树的子树_数据结构—树|二叉树|前序遍历、中序遍历、后序遍历【图解实现】...

    点击蓝字关注我们 AI研习图书馆,发现不一样的精彩世界 数据 结构 二叉树的遍历 一.树 在谈二叉树的知识点之前,我们首先来看一下树和图的基本概念.树:不包含回路的连通无向图,树是一种简单的非线性结构 ...

  5. 【数据结构笔记10】二叉树的先序、中序、后序遍历,中序遍历的堆栈/非递归遍历算法,层序遍历,确定一个二叉树,树的同构

    本次笔记内容: 3.3.1 先序中序后序遍历 3.3.2 中序非递归遍历 3.3.3 层序遍历 3.3.4 遍历应用例子 小白专场:题意理解及二叉树表示 小白专场:程序框架.建树及同构判别 文章目录 ...

  6. pat根据中序遍历和先序遍历_[leetcode/lintcode 题解] 前序遍历和中序遍历树构造二叉树...

    [题目描述] 根据前序遍历和中序遍历树构造二叉树. 在线评测地址: 九章算法 - 帮助更多中国人找到好工作,硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧​www.jiuzhang.com [样例 ...

  7. 关于树的前序遍历,中序遍历,后序遍历的相互转化(含代码实现)

    2019独角兽企业重金招聘Python工程师标准>>> 首先我们需要了解的是前序遍历.中序遍历.后序遍历的概念. 前序遍历: 1.首先访问根节点 2.然后遍历左子树 3.最后遍历右子 ...

  8. 树的遍历(中序,前序,后序)

    与只有一种逻辑遍历它们的线性数据结构(数组.链表.队列.堆栈等)不同,树可以以不同的方式遍历,常见的有中序遍历,前序遍历和后序遍历. 实现各种遍历的方法又包括: 以上图为例: 深度优先遍历:  (a) ...

  9. 已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

    二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或 ...

  10. 树的前序遍历、中序遍历、后序遍历详解

    1.前序遍历 对于当前节点,先输出该节点,然后输出他的左孩子,最后输出他的右孩子.以上图为例,递归的过程如下: (1):输出 1,接着左孩子: (2):输出 2,接着左孩子: (3):输出 4,左孩子 ...

最新文章

  1. java中JFrame类中函数addWindowListener(new WindowAdapter)
  2. EID:宏基因组测序在新发腹泻病毒鉴定中的应用
  3. 概率统计概念复习:MAPMLE
  4. Spring Boot开启的2种方式
  5. Excel Chart
  6. boost::process:std_out相关的测试程序
  7. RMAN 还原与恢复
  8. 高通驱动一键安装_一键重装神器,装系统简单的超乎想象!
  9. linux下设置好环境变量要重启计算机
  10. java batik svg_java使用batik转换svg文件
  11. STM32F4 OLED详解
  12. 全球人工智能与机器学习大会PPT
  13. 商务与经济统计学习 --概率
  14. android清理空间,安卓手机如何清理系统空间
  15. 脉冲响应不变法C语言程序,脉冲响应不变法-数字信号处理总结.ppt
  16. 【STM32Cube】学习笔记(二):超声波传感器
  17. 西门子200SMART(七)交叉引用
  18. UESTC 2018 Summer Training #4 Div.2
  19. datetime用法
  20. CAD格式刷怎么用?

热门文章

  1. C#控件之TreeView
  2. HDU3032_NimOrNotNim解题报告
  3. 2010-10-08在浏览器中兼容+jQuery3
  4. SQL中CONVERT转化函数的用法(转)
  5. 从TIN获取任意坐标点高程(原创)
  6. memcached—向memcached中保存Java实体需注意的问题
  7. 进入windows自启文件夹
  8. 44. 扑克牌的顺子(C++版本)
  9. Docker安装以及一些常用命令
  10. 三个箭头循环标志_摩托车6年免检,应该如何通过APP申请免检检验标志?