二叉树的前序,中序,后序遍历(非递归实现)

前序遍历
思路:遇到一个节点,就访问该节点,然后进栈,然后遍历左子树,遍历完成后,弹出栈顶节点并出栈,并访问右子树。

class Solution {
public:
 /*  
 伪代码:
1.栈初始化(空栈);
2.循环直到root为空且栈为空 
 2.1 当root不空时循环
    2.1.1 访问root;
     2.1.2 将root的值保存到栈中;
     2.1.3 遍历root的左子树。
 2.2 如果栈不空,则
    2.2.1 将栈顶元素弹出至root;
    2.2.2 遍历root的右子树。
*/
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        stack<TreeNode*> sta;
        while(root!=nullptr||!sta.empty())
        {
            if(root!=nullptr)
            {
                sta.push(root);
                res.push_back(root->val);
                root=root->left;
            }
            else
            {
                auto t=sta.top();
                sta.pop();
                root=t->right;
            }
        }
        return res;
    }
};

中序遍历
思路:和前序遍历类似。不同的仅仅只是访问的顺序移到出栈时。

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        stack<TreeNode*> sta;
        while(root!=nullptr||!sta.empty())
        {
            if(root!=nullptr)
            {
                sta.push(root);
                root=root->left;
            }
            else
            {
                auto t=sta.top();
                sta.pop();
                res.push_back(t->val);
                root=t->right;
            }
        }
        return res;
    }
};

后序遍历
思路:对于每个节点,都压入两遍,在循环体中,每次弹出一个节点赋给p,如果p仍然等于栈的头结点,说明p的孩子们还没有被操作过,应该把它的孩子们加入栈中,否则,访问p。也就是说,第一次弹出,将p的孩子压入栈中,第二次弹出,访问p。

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> vec;
        if(!root) return vec;
        stack<TreeNode*> sta;
        TreeNode* P=root;
        sta.push(P);
        sta.push(P);
        while(!sta.empty())
        {
            P=sta.top();
            sta.pop();
            if(!sta.empty()&&P==sta.top())
            {               
            if(P->right){ sta.push(P->right); sta.push(P->right); }
            if(P->left){ sta.push(P->left); sta.push(P->left); }  
            }
            else
             vec.push_back(P->val);
        }
     return vec;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值