1.前序遍历:
/*
根节点先入栈。
for(栈非空)
do
{
栈顶元素出栈。依次压入右节点,左节点。
}
end for
*/
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if(root==NULL) return res;
stack<TreeNode*> st;
st.push(root);
while(!st.empty())
{
TreeNode* temp = st.top();
st.pop();
res.push_back(temp->val);
if(temp->right) st.push(temp->right);
if(temp->left) st.push(temp->left);
}
return res;
2.中序遍历
从根节点开始,不断访问左节点。沿路径入栈。出栈后访问右节点执行相同的操作。
vector<int> inorderTraversal(TreeNode* root) {
/*
用栈。对于每个节点,走到最左端,沿着路径压栈。
然后逐个弹出节点,对每个节点的右节点循环此操作。
*/
vector<int> res;
TreeNode* temp = root;
stack<TreeNode*> zh;
if(root==NULL) return res;
while(temp||!zh.empty())
{
while(temp)
{
zh.push(temp);
temp = temp->left;
}
temp = zh.top();
zh.pop();
res.push_back(temp->val);
temp = temp->right;
}
return res;
}
3.后序遍历:
/*
对于节点p可以分情况讨论
1. p如果是叶子节点,直接输出
2. p如果有孩子,且孩子没有被访问过,则按照右孩子,左孩子的顺序依次入栈
3. p如果有孩子,而且孩子都已经访问过,则访问p节点
对于每个节点,都压入两遍,在循环体中,每次弹出一个节点赋给p,如果p仍然等于栈的头结点,说明p的孩子们还没有被操作过,
应该把它的孩子们加入栈中,否则,访问p。也就是说,第一次弹出,将p的孩子压入栈中,第二次弹出,访问p。
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if(root==NULL) return res;
stack<TreeNode*> st;
st.push(root);
st.push(root);
TreeNode* temp = root;
while(!st.empty())
{
temp = st.top();
st.pop();
if(!st.empty() && temp == st.top())
{
if(temp->right)
{
st.push(temp->right);
st.push(temp->right);
}
if(temp->left)
{
st.push(temp->left);
st.push(temp->left);
}
}
else
{
res.push_back(temp->val);
}
}
return res;
}
};