栈和递归的关系 144:Binary Tree Preorder Traversal

前序遍历:根左右
//用栈来实现非递归解法
/**
* Definition for a binary tree node.
* 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;
if(root == NULL)
return res;
stack<TreeNode*> stack;
stack.push(root); while(!stack.empty()){
TreeNode* c = stack.top();
stack.pop();
res.push_back(c->val);
if(c->right)
stack.push(c->right);
if(c->left)
stack.push(c->left);
}
return res;
}
};
//递归解法,注意res是全局的,要放在遍历函数外面
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> res;
vector<int> preorderTraversal(TreeNode* root) { if(root){
res.push_back(root->val);
preorderTraversal(root->left);
preorderTraversal(root->right);
}
return res;
}
};
中序遍历:左根右

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public: vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> res;
if(root == NULL) return res; //若根节点为空则返回空
TreeNode* p = root;
while(p || !st.empty()){
while(p){
//先将根节点入栈,再将它所有的左节点入栈
st.push(p);
p = p->left;
} p = st.top();
st.pop();
res.push_back(p->val);
p = p->right;
}
return res;
}
};
后序遍历:左右根

可以使其遍历顺序为根左右,然后逆序插入vector中,即每次在vector的头部插入结点值。在压入栈时先压入右结点再压入左结点则在出栈时就是先左后右了。
//解法一
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
if(!root) return {};
vector<int> res;
stack<TreeNode*> s{{root}};
while(!s.empty()){
TreeNode* t = s.top();
s.pop();
res.insert(res.begin(), t->val);
if(t->left) s.push(t->left);
if(t->right) s.push(t->right);
}
return res;
}
};
解法二:关键是判断当前这个结点:
1)它如果有左右结点是否已经入栈,若没有入栈则先将它的右结点入栈,再左结点入栈;如果它的左右结点已经入栈,则这个结点就可以直接加入容器vector里了。
2)如果它是叶子结点(没有左右结点),则直接加入vector中。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
if(!root) return {};
vector<int> res;
stack<TreeNode*> s{{root}};
TreeNode* head = root; //head初始化
while(!s.empty()){
TreeNode* t = s.top();
if((!t->left && !t->right) || t->left==head || t->right==head){
//当t为叶子结点 或t的左结点或右结点为head,即已经入栈了
res.push_back(t->val);
s.pop();
head = t;
}
else{
if(t->right) s.push(t->right);
if(t->left) s.push(t->left);
}
}
return res;
}
};




leetcode已经分别定义了类NestedInteger中的三个函数:
1)isInteger():若当前这个NestedInteger是单个整数返回true;
2)getInteger():返回当前这个单个的整数;
3)getList():返回当前这个列表。
/**
* // This is the interface that allows for creating nested lists.
* // You should not implement it, or speculate about its implementation
* class NestedInteger {
* public:
* // Return true if this NestedInteger holds a single integer, rather than a nested list.
* bool isInteger() const;
*
* // Return the single integer that this NestedInteger holds, if it holds a single integer
* // The result is undefined if this NestedInteger holds a nested list
* int getInteger() const;
*
* // Return the nested list that this NestedInteger holds, if it holds a nested list
* // The result is undefined if this NestedInteger holds a single integer
* const vector<NestedInteger> &getList() const;
* };
*/
class NestedIterator {
public:
stack<NestedInteger> s; NestedIterator(vector<NestedInteger> &nestedList) {
for(int i=nestedList.size()-; i>=; i--)
//倒序插入 是为了弹出时是正序的
s.push(nestedList[i]);
} int next() {
//返回下一项的值
NestedInteger t = s.top();
s.pop();
return t.getInteger(); //获取对应整数 } bool hasNext() {
//若下一项有值,返回true
while(!s.empty()){
NestedInteger t = s.top();
if(t.isInteger())
return true; //若下一个数是单个整数,返回true
s.pop();
//若下一个数是一个列表,使用getList()得到列表的每个整数倒序插入到栈中
for(int i=t.getList().size()-; i>=; i--)
s.push(t.getList()[i]);
}
return false;
}
}; /**
* Your NestedIterator object will be instantiated and called as such:
* NestedIterator i(nestedList);
* while (i.hasNext()) cout << i.next();
*/
栈和递归的关系 144:Binary Tree Preorder Traversal的更多相关文章
- C++版 - LeetCode 144. Binary Tree Preorder Traversal (二叉树先根序遍历,非递归)
144. Binary Tree Preorder Traversal Difficulty: Medium Given a binary tree, return the preorder trav ...
- 二叉树前序、中序、后序非递归遍历 144. Binary Tree Preorder Traversal 、 94. Binary Tree Inorder Traversal 、145. Binary Tree Postorder Traversal 、173. Binary Search Tree Iterator
144. Binary Tree Preorder Traversal 前序的非递归遍历:用堆来实现 如果把这个代码改成先向堆存储左节点再存储右节点,就变成了每一行从右向左打印 如果用队列替代堆,并且 ...
- 【LeetCode】144. Binary Tree Preorder Traversal (3 solutions)
Binary Tree Preorder Traversal Given a binary tree, return the preorder traversal of its nodes' valu ...
- [LeetCode] 144. Binary Tree Preorder Traversal 二叉树的先序遍历
Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binary tr ...
- (二叉树 递归) leetcode 144. Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes' values. Example: Input: [1,null,2,3 ...
- Java [Leetcode 144]Binary Tree Preorder Traversal
题目描述: Given a binary tree, return the preorder traversal of its nodes' values. For example:Given bin ...
- 144 Binary Tree Preorder Traversal(二叉树先序遍历Medium)
题目意思:二叉树先序遍历,结果存在vector<int>中 解题思路:1.递归(题目中说用递归做没什么意义,我也就贴贴代码吧) 2.迭代 迭代实现: class Solution { pu ...
- 【LeetCode】144. Binary Tree Preorder Traversal
题目: Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binar ...
- 【LeetCode】144. Binary Tree Preorder Traversal 解题报告(Python&C++&Java)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 迭代 日期 题目地址:https://leetc ...
随机推荐
- opennebula 开发记录
/app/opennebula/var//datastores/1/12933297f0ffeba3e55bbccabcb3153b to 127.0.0.1:/app/opennebula/data ...
- 22-Two(公共子序列的个数)
http://acm.hdu.edu.cn/showproblem.php?pid=5791 Two Time Limit: 2000/1000 MS (Java/Others) Memory ...
- lucene 第一天
Lucene/Solr 第一天 1. 课程计划 Lucene介绍 全文检索流程介绍 a) 索引流程 b) 搜索流程 Lucene入门程序 a) 索引实现 b) 搜索实现 分词器 a) 分词介绍 b ...
- FlyweightPattern(23种设计模式之一)
设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...
- poj1722 SUBTRACT
应该是基础的dp练手题 线性dp最主要的就是关于阶段的划分,这个题中我没想到的一点就是开状态的时候使用了前i个数能合成的数来记录 我自己的想法就是类似于区间dp这样的记录方法,这种方法确实开了很多冗余 ...
- [GO]map做函数参数
package main import "fmt" func test(m map[int]string) { delete(m, ) } func main() { m := m ...
- 新编html网页设计从入门到精通 (龙马工作室) pdf扫描版
新编html网页设计从入门到精通共分为21章,全面系统地讲解了html的发展历史及4.0版的新特性.基本概念.设计原则.文件结构.文件属性标记.用格式标记进行页面排版.使用图像装饰页面.超链接的使用. ...
- C#导出Excel-利用特性自定义数据
网上C#导出Excel的方法有很多.但用来用去感觉不够自动化.于是花了点时间,利用特性做了个比较通用的导出方法.只需要根据实体类,自动导出想要的数据 1.在NuGet上安装Aspose.Cells或 ...
- VS Code基本使用
1. Activity Bar 1.1 Explorer 1.1.1. OPEN EDITORS 所有在右侧编辑区打开的文件列表 1.1.2 {PROJECTNAME} 某个文件夹下的文件树 1.2 ...
- 最小生成树(kruscal算法)
其实kruscal算法很简单,把边从小到大排一遍,如果加入此边形成环,就不加,知道这棵树有n-1条边. 代码如下(一定要理解): #include<iostream> #include&l ...