问题描述
递归版请见:Leetcode|二叉树的遍历方式|144/94/145.二叉树的前序/中序/后序遍历[递归版]
这里仅提供前序的截图,中序和后序问题大家都懂,就不赘述了
一、二叉树的前序迭代遍历
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
if (!root) return {};
vector<int> vec;
stack<TreeNode*> stk;
auto node = root;
while (!stk.empty() || node) {
// 1.遍历到最左子节点
while (node) {
// 前序:填充vec在node->left和node->right前
vec.emplace_back(node->val);
stk.emplace(node);
node = node->left;
}
node = stk.top(); stk.pop();
// 2.遍历最左子节点的右子树
node = node->right;
}
return vec;
}
};
二、二叉树的中序迭代遍历
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
if (!root) return {};
vector<int> vec;
stack<TreeNode*> stk;
auto node = root;
while (!stk.empty() || node) {
// 1.遍历到最左子节点
while (node) {
stk.emplace(node);
node = node->left;
}
node = stk.top(); stk.pop();
// 中序:填充vec在node->left和node->right中间
vec.emplace_back(node->val);
// 2.遍历最左子节点的右子树
node = node->right;
}
return vec;
}
};
三、二叉树的后序迭代遍历
后序遍历相对复杂一点,不过我已将注释写好,相信大家会轻松理解
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
if (!root) return {};
vector<int> vec;
stack<TreeNode *> stk;
TreeNode *prev = nullptr;
auto node = root;
while (!stk.empty() || node) {
// 1.遍历到最左子节点
while (node) {
stk.emplace(node);
node = node->left;
}
node = stk.top(); stk.pop();
// 2.遍历最左子节点的右子树(右子树存在 && 未访问过)
if (node->right && node->right != prev) {
// 重复压栈以记录当前路径分叉节点
stk.emplace(node);
node = node->right;
} else {
// 后序:填充vec在node->left和node->right后面
// 注意:此时node的左右子树应均已完成访问
vec.emplace_back(node->val);
// 避免重复访问右子树[记录当前节点便于下一步对比]
prev = node;
// 避免重复访问左子树[设空节点]
node = nullptr;
}
}
return vec;
}
};