算法笔记_面试题_4.树的遍历(前序/中序/后续遍历)
目录
题目
解答
递归的方法
迭代的方法-前序遍历
迭代的方法-中序遍历
迭代的方法-后序遍历
最优解之一
题目
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.树的遍历(前序/中序/后续遍历)相关推荐
- 【笔记】二叉树递归算法和非递归算法的实现 先序/中序/后续遍历 打印结点以及顺序数 构造二叉树
递归先序遍历和中序遍历 先序: void preorder(bnode *t){if(t!=NULL){ visit(t);preorder(t->lchild); preorder(t-> ...
- 二叉树前序中序后续线索树_后序线索二叉树怎么画 线索二叉树基本操作详解 - 办公软件 - 服务器之家...
后序线索二叉树怎么画 线索二叉树基本操作详解 发布时间:2017-05-23 来源:服务器之家 遍历二叉树是以一定规则将二叉树中结点排列成一个线性序列,得到二叉树中结点的先序,中序或后序序列.这实际上 ...
- 二叉树前序中序后续线索树_二叉树的先序,中序,后序遍历以及线索二叉树的遍历...
二叉树的先序,中序,后序遍历以及线索二叉树的遍历 (2008-05-04 17:52:49) 标签: 杂谈 C++ 二叉树的先序,中序,后序遍历以及线索二叉树的遍历 头文件 //*********** ...
- c++ 删除二叉树的子树_数据结构—树|二叉树|前序遍历、中序遍历、后序遍历【图解实现】...
点击蓝字关注我们 AI研习图书馆,发现不一样的精彩世界 数据 结构 二叉树的遍历 一.树 在谈二叉树的知识点之前,我们首先来看一下树和图的基本概念.树:不包含回路的连通无向图,树是一种简单的非线性结构 ...
- 【数据结构笔记10】二叉树的先序、中序、后序遍历,中序遍历的堆栈/非递归遍历算法,层序遍历,确定一个二叉树,树的同构
本次笔记内容: 3.3.1 先序中序后序遍历 3.3.2 中序非递归遍历 3.3.3 层序遍历 3.3.4 遍历应用例子 小白专场:题意理解及二叉树表示 小白专场:程序框架.建树及同构判别 文章目录 ...
- pat根据中序遍历和先序遍历_[leetcode/lintcode 题解] 前序遍历和中序遍历树构造二叉树...
[题目描述] 根据前序遍历和中序遍历树构造二叉树. 在线评测地址: 九章算法 - 帮助更多中国人找到好工作,硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧www.jiuzhang.com [样例 ...
- 关于树的前序遍历,中序遍历,后序遍历的相互转化(含代码实现)
2019独角兽企业重金招聘Python工程师标准>>> 首先我们需要了解的是前序遍历.中序遍历.后序遍历的概念. 前序遍历: 1.首先访问根节点 2.然后遍历左子树 3.最后遍历右子 ...
- 树的遍历(中序,前序,后序)
与只有一种逻辑遍历它们的线性数据结构(数组.链表.队列.堆栈等)不同,树可以以不同的方式遍历,常见的有中序遍历,前序遍历和后序遍历. 实现各种遍历的方法又包括: 以上图为例: 深度优先遍历: (a) ...
- 已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法
二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或 ...
- 树的前序遍历、中序遍历、后序遍历详解
1.前序遍历 对于当前节点,先输出该节点,然后输出他的左孩子,最后输出他的右孩子.以上图为例,递归的过程如下: (1):输出 1,接着左孩子: (2):输出 2,接着左孩子: (3):输出 4,左孩子 ...
最新文章
- java中JFrame类中函数addWindowListener(new WindowAdapter)
- EID:宏基因组测序在新发腹泻病毒鉴定中的应用
- 概率统计概念复习:MAPMLE
- Spring Boot开启的2种方式
- Excel Chart
- boost::process:std_out相关的测试程序
- RMAN 还原与恢复
- 高通驱动一键安装_一键重装神器,装系统简单的超乎想象!
- linux下设置好环境变量要重启计算机
- java batik svg_java使用batik转换svg文件
- STM32F4 OLED详解
- 全球人工智能与机器学习大会PPT
- 商务与经济统计学习 --概率
- android清理空间,安卓手机如何清理系统空间
- 脉冲响应不变法C语言程序,脉冲响应不变法-数字信号处理总结.ppt
- 【STM32Cube】学习笔记(二):超声波传感器
- 西门子200SMART(七)交叉引用
- UESTC 2018 Summer Training #4 Div.2
- datetime用法
- CAD格式刷怎么用?