4.1深度优先遍历的迭代方式
leetcode :
144.二叉树的前序遍历
94.二叉树的中序遍历
145.二叉树的后序遍历
递归的实现:
每一次调用递归: 都会将函数在本次递归中所产生的局部变量, 参数值 和返回地址等压入调用栈中;
递归返回时: 从栈顶 弹出上一次递归的各项参数, 所以递归可以返回上一层的位置;
从而我们知道, 栈可以实现二叉树的递归方式;
同样,我们本次使用栈 实现二叉树的 迭代方式;
使用迭代方式的遍历过程中, 有两关键点:
- 访问节点( 将节点压入栈中);
- 处理节点(将节点从栈中取出, 然后将节点中的数据部分存入到结果集中);
整体思路:
前序,后序遍历, 先将根节点入栈,
接着循环中,是先处理节点,然后开始访问节点;
中序遍历: 先将当前节点赋值为根节点;
在循环中, 先处理栈中节点, 将节点中的数据存到结果集中, 然后才开始 访问节点;
1. 前序遍历的迭代方式
由于栈的后进先出的特性;
前序遍历的输出顺序是: 中,左,右;
根据以上两点,可知:
所以入栈的 顺序: 中 ,右 , 左, 中 ;
1.1 步骤
创建 结果集 向量容器, result;
创建 节点型 stack 容器适配器, st;
条件判断, 当根节点为空, 返回结果集;
将根节点 压入到栈中;
执行循环, 当栈不为空:
新建当前节点, 赋值为栈顶的节点的引用;移除栈顶节点;将当前节点中的数值保存到结果集中;条件判断, 当前节点的右节点不为空, 将当前节点的右节点压入栈中;条件判断, 当前节点的左子树不为空, 将当前节点的左节点压入到栈中;
循环结束, 返回结果集;
1.2 code
#include "vector"
#include "stack"using namespace std;struct TreeNode{int val;TreeNode* left;TreeNode* right;// 默认构造函数, 列表形式;TreeNode(int x): val(x), left(nullptr), right(nullptr){}};class Solution1{vector<int> preOrder(TreeNode* root) {vector<int> result;stack<TreeNode*> st;// 当根节点为空时, 返回结果集;if( root == nullptr ) return result;// 根节点不为空,压入栈中;st.push(root);while( !st.empty()){TreeNode* cur_node = st.top(); // 当前节点 赋值为 栈顶的节点;// 移除栈顶节点;st.pop();result.push_back(cur_node->val);if(cur_node->right) st.push(cur_node->right);if(cur_node->left) st.push(cur_node->left);}return result;}
};
关键点:
- 处理: 将元素放进result 数组中;
- 访问: 遍历节点;
前序遍历中: 先访问的是中间节点, 要处理的元素也是中间节点; 即, 访问的元素和 要处理的元素顺序是一致的,都是中间节点;
2. 中序遍历的迭代方式
中序遍历: 左,中, 右; 先访问根节点, 然后一层一层的向下访问, 直到到达树左边的最底部, 在开始处理节点,造成了处理顺序和访问顺序不一致的;
故
- 访问节点: 使用指针来遍历;
- 处理节点: 使用栈来处理;
关键点:
先访问节点, 直到当前节点更新为空节点;
开始处理节点;
2.1 步骤
创建 结果集 向量容器, result;
创建 节点型 stack 容器适配器, st;
令当前节点 赋值为 根节点;
执行循环, 当 当前节点不为空, 或者 栈不为空:
条件判断: 当前节点 不为空,
将当前节点压入栈;
当前节点更新为 当前节点的左节点;
否则, 当前节点为空:
当前节点赋值为 栈顶的节点引用;
移除栈顶的节点;
将当前节点中的 数值存入到 结果集中;
当前节点 更新为 当前节点的右节点;
循环结束, 返回结果集;
class Solution2{public:vector<int> inOrder(TreeNode* root) {vector<int> result; // 用于 处理节点, 将节点中的数值保存其中;stack<TreeNode *> st; // 用于访问节点时, 将节点入栈;TreeNode* cur_node = root;// 开始遍历 树的节点和栈中的节点;while( cur_node != nullptr|| !st.empty() ) {// 循环, 当前节点不为空, 访问没到到位,未到叶子节点; 栈不为空, 处理没有到位;// 先进行访问;if( cur_node != nullptr){ // 如果当前节点未到达, 叶子节点;// 依次 将访问的节点入栈;st.push(cur_node);cur_node = cur_node->left; // 将访问节点 更新为 当前节点的左子树;}else{ // 访问结束, 开始处理节点;cur_node = st.top(); // 返回栈顶元素的引用;result.push_back(cur_node->val); // 处理节点, 节点中的元素入栈;st.pop();cur_node = cur_node->right;}}return result;}};
3. 后序遍历的迭代方式
前序: 入栈顺序, 中, 右, 左; 结果集中的元素: 中, 左, 右;
后序:
后序遍历, 是在前序遍历的 基础上,进行两点修改:
- 节点入栈的顺序改变;
- 结果集中的 元素,需要倒序一下;
3.1 步骤
创建 结果集 向量容器, result;
创建 节点型 stack 容器适配器, st;
条件判断, 当根节点为空, 返回结果集;
将根节点 压入到栈中;
执行循环, 当栈不为空:
新建当前节点, 赋值为栈顶的节点的引用;移除栈顶节点;将当前节点中的数值保存到结果集中;条件判断, 当前节点的右节点不为空, 将当前节点的右节点压入栈中;条件判断, 当前节点的左子树不为空, 将当前节点的左节点压入到栈中;
反转结果集,
循环结束, 返回结果集;
class Solution {public:vector<int> postorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode* > st;if(root == nullptr) return result; // 根节点为空, 返回结果集;st.push(root) ; // 先将根节点入栈;while( !st.empty() ){// 当 栈中的节点不为空时,// 取出栈顶节点,进行处理;TreeNode* cur_node = st.top();result.push_back(cur_node->val);st.pop();// 访问节点;if(cur_node->left) st.push( cur_node->left);if(cur_node->right) st.push( cur_node->right);}reverse(result.begin(), result.end());return result;}};
4.1深度优先遍历的迭代方式相关推荐
- Python二叉树的三种深度优先遍历
Python二叉树的三种深度优先遍历 一.广度优先遍历和深度优先遍历 对二叉树进行遍历(traversal)是指依次对树中每个节点进行访问,在遍历的过程中实现需要的业务. 对树的遍历方式有广度优先遍历 ...
- JAVA 获取树的所有路径-深度优先遍历和广度优先
1.示例 树的结构 示例中本身构建了图片中的这棵树 树节点模型: public class TreeNode {String value;List<TreeNode> children;p ...
- 数组反向遍历ios_iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式
iOS开发实用技巧-Objective-C中的各种遍历(迭代)方式 说明: 1)该文简短介绍在iOS开发中遍历字典.数组和集合的几种常见方式. 2)该文对应的代码可以在下面的地址获得:https:// ...
- 树形结构:迭代方式遍历树,宽度优先,先序遍历,中序遍历,后序遍历
迭代的方式处理树,就必须清楚你将要访问的顺序,对应的就是指针怎么走,你必须很清楚 树的宽度优先搜索,他是一层一层的访问,就搞不清楚怎么划分子问题了,但是你访问的顺序 你很清楚,那么就使用迭代的方式实现 ...
- 分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_数据结构与算法:三十张图弄懂「图的两种遍历方式」...
原创: 进击的HelloWorld1 引言遍历是指从某个节点出发,按照一定的的搜索路线,依次访问对数据结构中的全部节点,且每个节点仅访问一次. 在二叉树基础中,介绍了对于树的遍历.树的遍历是指从根节点 ...
- 深度优先遍历访问的边集合_数据结构与算法: 三十张图弄懂「图的两种遍历方式」...
1 引言 遍历是指从某个节点出发,按照一定的的搜索路线,依次访问对数据结构中的全部节点,且每个节点仅访问一次. 在二叉树基础中,介绍了对于树的遍历.树的遍历是指从根节点出发,按照一定的访问规则,依次访 ...
- 邻接矩阵的存储方式实现图的广度和深度优先遍历
在做图的邻接矩阵之前,先做好准备工作,定义存储类型,声明队列的操作(在广度优先遍历中使用) #include <stdio.h> #include <stdlib.h> #in ...
- 实验报告C语言实现图的深度遍历,图的深度优先遍历的C语言实现.pdf
图的深度优先遍历的C语言实现.pdf 维普资讯 九 江 职 业 技 术 学 院 学 报 JournalofJiujiangVocational&TechnicalCollege 2004.2 ...
- 三十二、图的创建深度优先遍历(DFS)广度优先遍历(BFS)
一.图的基本介绍 为什么要有图 前面我们学了线性表和树 线性表局限于一个直接前驱和一个直接后继的关系 树也只能有一个直接前驱也就是父节点 当我们需要表示多对多的关系时, 这里我们就用到了图. 图的举例 ...
- 多级树的深度优先遍历与广度优先遍历(Java实现)
目录 多级树的深度优先遍历与广度优先遍历(Java实现) 节点模型 深度优先遍历 广度优先遍历 多级树的深度优先遍历与广度优先遍历(Java实现) 深度优先遍历与广度优先遍历其实是属于图算法的一种,多 ...
最新文章
- 【 C 】动态内存分配实用案例(一)之读取、排序和打印一列整形值
- mysql 游标异常_mysql中的游标和异常捕捉
- SQL Server 下的 获取当月最后一天
- 并不是所有的 Github 项目写在简历上都加分
- ITK:使用写访问权迭代图像中的区域
- leetcode 67. 二进制求和(C语言)
- 【BZOJ3930】选数(莫比乌斯反演倍数形式,杜教筛)
- as3调用外部swf里的类的方法
- CodeForces Manthan 2011 D. Optical Experiment(动态规划)
- ViewPager VS ViewFilpper
- 使用css的类名交集复合选择器 《转》
- 转:高级PHP应用程序漏洞审核技术
- 微信公众号开发接入_官方文档
- 机器学习基础(六)贝叶斯统计
- Win系统 - 关于GPU,你需要长的“姿势”
- TP6手册理解之架构·服务
- 在openSUSE上编译aMule-DLP
- AMiner权威发布区块链大数据报告(附下载)
- 制作 win10 u 盘安装盘
- VB运行后去除窗体标题栏且可改变窗口大小及移动窗体