前序
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> v;
stack<TreeNode*> st;
TreeNode* cur = root;
while(!st.empty()||cur)
{
while(cur)
{
v.push_back(cur->val);
st.push(cur);
cur = cur->left;
}
TreeNode* top = st.top();
st.pop();
cur = top->right;
}
return v;
}
};
根节点入数组,左链入栈。根据栈先入后出的特点,将栈头依次取出,遍历右节点。
中序
//vector 联合 stack
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> v;
stack<TreeNode*> st;
TreeNode* cur = root;
while(cur || !st.empty())
{
while(cur)
{
st.push(cur);
cur = cur->left;
}
TreeNode* top = st.top();
st.pop();
v.push_back(top->val);
cur = top->right;
}
return v;
}
};
前序和中序的思路相似,都是数组联合栈的思想,区别是将左链完全入栈后,将栈头数值入数组,并遍历top->right;
后序
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> v;
stack<TreeNode*> st;
TreeNode* cur = root;
TreeNode* prev = nullptr;
while(cur || !st.empty())
{
while(cur)
{
st.push(cur);
cur = cur->left;
}
TreeNode* top = st.top();
//如果右为空,或者右孩子等于上一个访问的节点,说明右树都访问过了
//取出当前节点访问
//prev永远在top的后面,所以可以用来判断top是否走过这个节点
if(top->right == nullptr || prev == top->right)
{
v.push_back(top->val);
st.pop();
prev = top;
cur = nullptr;
}
else
{
cur = top->right;
}
}
return v;
}
};
思想:后序与之前不同的是,左链入栈后,在栈顶指针存在右孩子的情况下,在栈中第一次访问到栈顶的时候,不能入数组,第二次的时候才可以,所以加入了prev指针,用来判断第几次访问top。