目录
1.前序
一路向左遍历就是根->左,自然先访问根,符合前序的顺序,可以直接入v
vector<int> preorderTraversal(TreeNode* root) {
// write code here
vector <int > v;
stack<TreeNode*> s;
TreeNode* cur=root;
while(cur || !s.empty())
{
while(cur)
{
v.push_back(cur->val);
s.push(cur);
cur=cur->left;
}
TreeNode* top=s.top();
s.pop();
cur=top->right;
}
return v;
}
2.中序
一路向北还是可以先访问根,但是现在中序我们先需要左
vector<int> inorderTraversal(TreeNode* root) {
vector <int > v;
stack<TreeNode* > s;
TreeNode* cur = root;
while (cur || !s.empty())
{
//中序是左 根 右,所以一路向左的时候不能同时把节点保存在v,因为向左都是先访问根,然后走他的左,你连根都不想要为什么全部加到v?
while (cur)
{
s.push(cur); //保存在栈里,因为这里有根节点,可以帮助找到右子树
cur = cur->left;
}
TreeNode* top = s.top(); //栈顶,左节点/父节点
s.pop();
v.push_back(top->val); //此时的父/左节点就需要加到v
cur = top->right; //走右
}
return v;
}
3.后序
按照之前的思路,一路向左之后,取栈顶,但是不能直接访问,应该访问他的右子树然后走子问题,走完右之后,再次来到这个根节点,如果根的右为空,直接访问根,如果根再次被访问,也直接把访问根
所以需要保存一下上一个访问的节点
vector<int> postorderTraversal(TreeNode* root) {
vector <int > v;
if(!root) return v;
stack<TreeNode* > s1;
//s1.push(root);
TreeNode* cur=root;
TreeNode* prev=nullptr; //上一个访问的节点
while(!s1.empty()||cur)
{
while(cur)
{
s1.push(cur);
cur=cur->left;
}
TreeNode* top=s1.top();
if(!top->right || top->right==prev)
{
s1.pop();
v.push_back(top->val);
prev=top;
}
else
cur=top->right;
}
return v;
}