1. 前序遍历非递归写法
遍历规则:左 + 右 + 根
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> ret;
if(root == nullptr)
return ret;
TreeNode* cur = root;
stack<TreeNode*> s;
while(cur || !s.empty())
{
while(cur)
{
ret.push_back(cur->val);
s.push(cur->right);
cur = cur->left;
}
// 根节点和左子树都已经遍历完,现在应该遍历右子树
// 将右子树当成一棵新的树进行遍历
cur = s.top();
s.pop();
}
return ret;
}
};
2. 中序遍历非递归写法
遍历规则:左 + 根 + 右
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> ret;
if(root == nullptr)
return ret;
TreeNode* cur = root;
stack<TreeNode*> s;
while(cur || !s.empty())
{
while(cur)
{
s.push(cur);
cur = cur->left;
}
cur = s.top();
s.pop();
ret.push_back(cur->val);
// 左子树和根节点已经遍历完,此时应遍历右子树
// 将右子树看成一棵新的树进行遍历
cur = cur->right;
}
return ret;
}
};
3. 后序遍历非递归写法
遍历规则:左 + 右 + 根
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> ret;
if(root == nullptr)
return ret;
stack<TreeNode*> s;
TreeNode* cur = root;
TreeNode* prev = nullptr;//用于标记前一个被访问的节点
while(cur || !s.empty())
{
while(cur)
{
s.push(cur);
cur = cur->left;
}
TreeNode* top = s.top();
// 保存了走左侧路径的所有节点,相当于已经遍历了左子树,现在需要分别遍历右子树和根节点
// 此时从stack中取出的节点有两种情况:没有右子树或有右子树
// 1. 没有右子树则直接遍历根节点
// 遍历根节点的条件又分为两种:没有右子树和右子树已经遍历过
if(top->right == nullptr || top->right == prev)
{
ret.push_back(top->val);
s.pop();
// 标记刚刚访问的节点
prev = top;
}
// 2. 有右子树则将右子树当成一棵新的树进行遍历
else
{
cur = top->right;
}
}
return ret;
}
};