栈和递归的关系 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 ...
随机推荐
- 制作第三方SDK静态库、.framework(修正)
静态库和动态库的存在形式 静态库: .a 和 .framework 动态库: .dylib 和 .framework 静态库和动态库的使用区别: 静态库:链接时,静态库会被完整地复制 到 可执行文件中 ...
- Luogu 1606 [USACO07FEB]白银莲花池Lilypad Pond
感觉应当挺简单的,但是弄了好久……菜死了 如果不考虑那些为$1$的点,直接跑个最短路计数就好了,但是我们现在有一些边可以不用付出代价,那么只要在连边的时候先预处理搜一下就好了. 原来的想法是拆点,但是 ...
- Django ——Timezone 处理
Django ——Timezone 处理 https://blog.csdn.net/qq_37049781/article/details/79347278 2018年02月22日 14:50:24 ...
- Xcode弱网测试工具
Network Link Conditioner Network Link Conditioner工具是Mac下提供的一个弱网测试工具. 安装Network Link Conditioner Xcod ...
- OSG3.2+Qt5.2.1+VS2012+OSGEarth 2.5编译问题记录
问题1:CMake Error at D:/Qt/Qt5.2.1/5.2.1/msvc2012_64_opengl/lib/cmake/Qt5Gui/Qt5GuiConfigExtras.cmake: ...
- excel中的绝对引用和相对应用
六.相对引用和绝对引用 1.相对引用 单元格或单元格区域的相对引用是指相对于包含公式的单元格的相对位置.例如,单元格 B2 包含公式 =A1 ;Excel 将在距单元格 B2 上面一个单元 ...
- 第06章-渲染Web视图
1. 理解视图解析 将控制器中请求处理的逻辑和视图中的渲染实现解耦是Spring MVC的一个重要特性.如果控制器中的方法直接负责产生HTML的话,就很难在不影响请求处理逻辑的前提下,维护和更新视图. ...
- js 简单抽奖实现
大家在很多活动页面上都看到绚丽多彩的抽奖运用,网上也有比较多关于这方面的js和用as.今天我在工作的时候也要做个抽奖的运用.我之前没有写过这类的js,也不会as,就得屁颠屁颠的问度娘啦,虽然找到有js ...
- 编写高质量代码改善C#程序的157个建议——建议9: 习惯重载运算符
建议9: 习惯重载运算符 在开发过程中,应该习惯于使用微软提供给我们的语法特性.我想每个人都喜欢看到这样的语法特性: ; ; int total = x + y; 而不是用下面的语法来完成一样的事情: ...
- SQL之DML
DML(Data Manipulation Language)数据操纵语言statements are used for managing data within schema objects. 由D ...