用迭代模拟前序、中序、后序的递归

144. 二叉树的前序遍历 - 力扣(LeetCode)

94. 二叉树的中序遍历 - 力扣(LeetCode) 

145. 二叉树的后序遍历 - 力扣(LeetCode) 

 方法:设置一个stack和vector,stack用于模拟递归,而vector用于记录数据。

1、无论是前、中、后序都是从根一直向最左的节点递进。因此模拟依然如此。(同时用stack记录每一个根节点,0,1,3,8)

2、遍历右子树,对根节点出栈,向右跳转,根->right。这样也就结束模拟实现了。

 语言无法形容该过程,我们先看代码再加深理解。

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;//记录根节点
        vector<int> ret;
        TreeNode* cur=root;
        while(cur||!st.empty())
        {
            while(cur)//遍历每个根节点的左树
            {
                ret.push_back(cur->val);//记录数据
                st.push(cur);//每个遍历过的节点入栈
                cur=cur->left;
            }

            TreeNode* top=st.top();//记录栈顶节点
            st.pop();//出栈
            cur=top->right;//跳转到每个根的右树
        }
        return ret;
    }
};

代码对上图树的记录前序过程:

第一次循环从根节点5出发,进入while(cur)后一直往左迭代5->3->1->0->nullptr,从stack中弹出0,cur=0->right==nullptr,第二次循环cur是空,进入不了while(cur),直接cur=1->right==2。

第三次循环,cur不为空,stack记录了它的节点,vector记录了它的数值,cur=cur->left=nullptr。

跳出循环,cur=2->right==nullptr,第4次循环,直接跳过while(cur),cur=3->right==4。

第5次循环,第6次循环亦是如此不过多介绍(不然会导致文章又臭又长)

中序:

和前序一模一样不多解释

lass Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) 
    {
        vector<int> ret;
        stack<TreeNode*> st;

        TreeNode* cur=root;
        while(cur||!st.empty())
        {
            while(cur)
            {
                st.push(cur);
                cur=cur->left;
            }
           TreeNode* top=st.top();
           ret.push_back(top->val);//改为在左树底部记录数据
           st.pop();
           cur=top->right;
        }
        return ret;
    }
};

后序:

拥有着与前两者相同的模板,但又有些不一样是思想方式。因为在刚才的模板中,走完左节点后一定会结果根节点,才能从根节点过度到右节点。无法改变,那就忽略。

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) 
    {
        vector<int> ret;
        stack<TreeNode*> st;

        TreeNode* cur=root;
        TreeNode* lastNode=nullptr;//用于记录是否已经遍历过该节点
        while(cur||!st.empty())
        {
            while(cur)
            {
                st.push(cur);
                cur=cur->left;
            }

            //记录栈顶数据,用于向右跳转或者删除数据
           TreeNode* top=st.top();
           if(top->right==nullptr||lastNode==top->right)
           {
               //右节点不存在或者已经遍历过右节点时
               //记录该叶子节点(根节点)
               ret.push_back(top->val);
               lastNode=top;//记录走过的节点
               st.pop();//弹出栈
            }
            else
            {
                cur=top->right;
            }
        }
        return ret;
    }
};

代码对上图树的记录后序过程:

第一次循环从根节点5出发,进入while(cur)后一直往左迭代cur=5->3->1->0->nullptr,top=0,

0->right==nullptr,lastNode=0;且0被弹出栈,第二次循环cur依然为nullptr,则不进入while(cur)

top=1,top->right==2,cur=top->right==2,第三次循环cur=cur->left==nullptr,记录2,弹出栈。

后面的循环亦是如此

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值