树的非递归遍历——前序、中序、后序

树的递归遍历非常简单,也是写树的遍历时最常用的写法。但是我发现自己对树的非递归遍历并不十分熟悉,所以把三种非递归遍历都写了一遍,以后看到这篇记录博客也可以帮助自己好好回想熟悉一下。

Leetcode对应习题:前序中序后序

相对而言,这三种非递归遍历的难度——前序 < 中序 < 后序。

对于第三种(非递归后序遍历)方法,只要稍微调整下第18~19行三个节点push的顺序,就可以实现前中后序的遍历。

树的非递归前序:

 1 class Solution {
 2 public:
 3     vector<int> preorderTraversal(TreeNode* root) {
 4         vector<int> re;
 5         stack<TreeNode*> s;
 6         s.push(root);
 7         while(!s.empty()){
 8             TreeNode *temp = s.top();
 9             s.pop();
10             if(!temp) continue;
11             re.push_back(temp->val);
12             s.push(temp->right);
13             s.push(temp->left);
14         }
15         return re;
16     }
17 };

树的非递归中序:

 1 class Solution {
 2 public:
 3     vector<int> inorderTraversal(TreeNode* root) {
 4         stack<TreeNode*> s;
 5         vector<int> re;
 6         TreeNode *t = root;
 7         while(!s.empty() || t){
 8             while(t){
 9                 s.push(t);
10                 t = t -> left;
11             }
12             if(!s.empty()){
13                 TreeNode *temp = s.top();
14                 s.pop();
15                 re.push_back(temp->val);
16                 t = temp->right;
17             }
18         }
19         return re;
20     }
21 };

树的非递归后序遍历:

 1 class Solution {
 2 public:
 3     vector<int> postorderTraversal(TreeNode* root) {
 4         stack<pair<TreeNode*, bool> > s;
 5         vector<int> re;
 6         s.push(make_pair(root, false));
 7         bool visited;
 8         while(!s.empty()){
 9             pair<TreeNode*, bool> p = s.top();
10             s.pop();
11             visited = p.second;
12             if(!p.first){
13                 continue;
14             }
15             if(visited){
16                 re.push_back(p.first->val);
17             }else{
18                 s.push(make_pair(p.first, true));
19                 s.push(make_pair(p.first->right, false));
20                 s.push(make_pair(p.first->left, false));
21             }
22         }
23         return re;
24     }
25 };

原文地址:https://www.cnblogs.com/liangf27/p/9630936.html

时间: 2024-10-28 15:40:26

树的非递归遍历——前序、中序、后序的相关文章

二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种

首先,要感谢网上的参考资料. http://mengliao.blog.51cto.com/876134/1178079(作者:BlackAlpha) http://blog.csdn.net/fzh1900/article/details/14056735(作者:_云淡风轻) http://blog.csdn.net/stpeace/article/details/8138458(作者:stpeace) 二叉树是使用的比较广泛的一种数据结构,这里我写了二叉树的相关操作,包括初始化.新建.以及遍

树的非递归遍历(中序遍历)

中序 遍历的几种情况 分析1:什么时候访问根.什么时候访问左子树.什么访问右子树 当左子树为空或者左子树已经访问完毕以后,再访问根 访问完毕根以后,再访问右子树. 分析2:非递归遍历树,访问结点时,为什么是栈,而不是其他模型(比如说是队列). 先走到的后访问.后走到的先访问,显然是栈结构 分析3:结点所有路径情况 步骤1: 如果结点有左子树,该结点入栈: 如果结点没有左子树,访问该结点: 步骤2: 如果结点有右子树,重复步骤1: 如果结点没有右子树(结点访问完毕),根据栈顶指示回退,访问栈顶元素

树的非递归遍历

树是递归定义的,利用递归算法遍历树实现起来比较简单,然而难的是非递归遍历.非递归遍历需要借助栈这一数据结构来完成. 首先定义树的结点和构建链表栈: //定义树的节点 typedef struct Node { int data; struct Node* lchild; struct Node* rchild; }Node; //定义栈节点 typedef struct Stacknode { Node* tnode; struct Stacknode* next; }Stacknode;  /

面试之路(11)-java递归和非递归二叉树前序中序后序遍历

二叉树的遍历 对于二叉树来讲最主要.最基本的运算是遍历. 遍历二叉树 是指以一定的次序访问二叉树中的每个结点.所谓 访问结点 是指对结点进行各种操作的简称.例如,查询结点数据域的内容,或输出它的值,或找出结点位置,或是执行对结点的其他操作.遍历二叉树的过程实质是把二叉树的结点进行线性排列的过程.假设遍历二叉树时访问结点的操作就是输出结点数据域的值,那么遍历的结果得到一个线性序列. 从二叉树的递归定义可知,一棵非空的二叉树由根结点及左.右子树这三个基本部分组成.因此,在任一给定结点上,可以按某种次

树的遍历总结 (包括递归,非递归),轻松理解后序遍历

参考大神的神作:http://blog.csdn.net/fightforyourdream/article/details/16843303 对于后序遍历,我们理解为将右节点为先的先序遍历翻转,会思考上简单很多,就是用右节点为先的先序遍历做,再用第二个栈进行翻转,就是后序遍历.

树的非递归遍历:一种很好的算法

栈模拟非递归算法 递归算法的本质是利用函数的调用栈进行,实际上我们可以自行使用栈来进行模拟,这样的算法空间复杂度为O(h),h为二叉树的高度. 前序遍历 首先把根节点入栈,然后在每次循环中执行以下操作: 此时栈顶元素即为当前的根节点,弹出并打印当前的根节点. 把当前根节点的右儿子和左儿子分别入栈(注意是右儿子先入栈左儿子后入栈,这样的话下次出栈的元素才是左儿子,这样才符合前序遍历的顺序要求:根节点->左儿子->右儿子). 后序遍历 因为后序遍历的顺序是:左子树->右子树->根节点,

二叉树学习之非递归遍历

二叉树递归遍历可谓是学过数据结构的同仁都能想一下就能写出来,但在应聘过程我们常常遇到的是写出一个二叉树非递归遍历函数,接着上篇文章写二叉树的非递归遍历,先难后易,一步一步的来. 先上代码: #include "binarytree.h" #include <stack> #include <queue> #ifndef RECU #warning("RECU is not defined") /** *前序遍历(根左右) * *1.当前节点为

c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 4,层级遍历 二叉树的查找,求高度,求个数,求父节点,复制二叉树,释放二叉树 编译方法,用gcc编译不过去,用g++编译,命令如下: g++ -g nodestack.c nodequeue.c bintree.c

二叉树基础(创建方法,遍历方法(前序/中序/后序/层序、递归/非递归)

二叉树的创建及遍历是很多二叉树问题的基础,递归遍历逻辑清晰,代码简约漂亮,然则效率低下(所有递归方案的通病,非不得已不用递归): 非递归遍历高效,却不是能信手写出来的,特别是后续非递归遍历,相信很多资深码工也有这样的经历: 5年前学习了二叉树的非递归遍历,一个月前复习了并达到能熟练写出的程度,在不参考任何资料的情况下,今天却怎样也写不出来. 如果你也有过这种经历,恭喜你,这说明你是一个正常人…… 另一方面市面上有些国人写的教材,各种语法.逻辑错误层出不起,不知祸害了多少未来的码工,深感痛心. 印