原题链接:. - 力扣(LeetCode)
详细解答(非常推荐):. - 力扣(LeetCode)
在处理二叉树时,前序遍历(Preorder Traversal)是一种常用的树遍历方法,其基本步骤是:首先访问当前节点,然后遍历左子树,最后遍历右子树。前序遍历可以通过递归或迭代实现。在本篇博客中,我们将探讨如何使用迭代方法来实现前序遍历,并提供一个C++代码示例。
前序遍历的迭代实现
迭代实现前序遍历可以避免递归的深度限制,并且通常能更有效地利用内存。下面是使用栈(stack)实现的前序遍历的C++代码:
#include <vector>
#include <stack>
using namespace std;
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
if (!root) { // 检查根节点是否为空
return vector<int>(); // 返回空向量
}
stack<TreeNode*> st; // 创建一个栈来存储节点
st.emplace(root); // 将根节点推入栈中
vector<int> ans; // 存储前序遍历的结果
while (!st.empty()) { // 当栈不为空时
TreeNode* top = st.top(); // 获取栈顶节点
ans.emplace_back(top->val); // 将当前节点的值加入结果向量
st.pop(); // 弹出栈顶节点
if (top->right) {
st.emplace(top->right); // 将右子节点推入栈中
}
if (top->left) {
st.emplace(top->left); // 将左子节点推入栈中
}
}
return ans; // 返回前序遍历结果
}
};
代码解析
-
基础检查:
- 如果
root
为空,直接返回一个空向量,表示树为空。
- 如果
-
栈初始化:
- 创建一个栈
st
来存储遍历的节点。 - 将根节点
root
推入栈中。
- 创建一个栈
-
遍历过程:
- 使用
while
循环遍历栈中的节点。只要栈不为空,就继续循环。 - 每次从栈中弹出一个节点,将其值添加到结果向量
ans
中。 - 按照前序遍历的顺序,将右子节点和左子节点依次推入栈中。注意,右子节点推入栈中的顺序在左子节点之后,确保左子节点在遍历中先于右子节点。
- 使用
-
结果返回:
- 循环结束后,返回存储了前序遍历结果的向量
ans
。
- 循环结束后,返回存储了前序遍历结果的向量
颜色标记法遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
if(!root)//root为空
{
return vector<int>();
}
stack<pair<int, TreeNode*>> st;
st.emplace(0, root);
vector<int> ans;
while(!st.empty())
{
pair<int, TreeNode*> top = st.top();
st.pop();
if (top.second==nullptr) continue;
if(top.first==0)//没被使用
{
top.first = 1;
st.emplace(0, (top.second)->right);
st.emplace(1, top.second);
st.emplace(0, (top.second)->left);
}
else//top被使用过
{
ans.emplace_back((top.second)->val);
}
}
return ans;
}
};
总结
使用栈来实现前序遍历是一种有效的迭代方法,避免了递归带来的额外开销和深度限制。这个方法能够在 O(n) 的时间复杂度下完成遍历,其中 n 是树中的节点数。这种方法特别适用于处理大规模二叉树,确保遍历的高效性和稳定性。