栈和递归的关系 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 ...
随机推荐
- css四可见,部分可见和重叠半透明
<html> <head> <title>javascript</title> <style type="text/css"& ...
- SpringAOP02 自定义注解
1 自定义注解 1.1 创建自定义注解 从java5开始就可以利用 @interface 来定义自定义注解 技巧01:注解不能直接干扰程序代码的运行(即:注解的增加和删除操作后,代码都可以正常运行) ...
- boost 错误报告
#include <Windows.h> #include <boost/asio.hpp> 编译器会报错,fatal error C1189: #error : WinSo ...
- Mybaties原理图
- js原型链prototype与__proto__以及new表达式
对象模型的细节 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Details_of_the_Object_Model
- Hadoop深入学习:MapTask详解
转自:http://flyingdutchman.iteye.com/blog/1878775#bc2337280 Hadoop深入学习:MapTask详解 博客分类: Hadoop MapTask执 ...
- vee-validate表单校验的基本使用
今天主要记录一下用vee-validate来进行表单校验的几个基本使用.包括最基础的必填和长度校验:异步请求服务的校验(重名校验),还有延迟校验.如何引入等就不在这里赘述了,直接进入主题. 1.必填和 ...
- Oracle Cannot Update TOP N Issue, 请专家解答
大家好 上周写了匿名方法一文,很多读者,很高兴,相信我们已经从大伙的回复中,对.NET又有了更深刻的认识. 好,现在说主题,各类数据库都有相应更新本表top n的方案.现在我一一举例 首先看表结构如下 ...
- Job-Show Liang,你来掌管诺基亚王国,可好?
保留我一向高大上风格,开头当然来一个段子 在即将到来MWC(Mobile World Congress缩写,世界移动通信大会),很高兴能听到小诺来参展,我不得不给它32个赞,因为小诺已经好几届没有浮头 ...
- React 使用browserHistory项目访问404问题
最近项目里面用到了React但是发布到iis站点之后,路由地址 刷新访问直接404错误.查阅资料之后发现是iis缺少配置URL重写 的问题导致的.下面我们来图形化配置,简单的配置下IIS 打开IIS使 ...