代码随想录算法训练营第16天|二叉树前中后序迭代法遍历

本文详细介绍了如何使用迭代法实现二叉树的前序、中序和后序遍历,强调了栈在过程中的关键作用,以及如何通过调整顺序和反转数组来实现后序遍历。作者还分享了在实现过程中遇到的空指针问题和栈操作的注意事项。
摘要由CSDN通过智能技术生成

代码随想录算法训练营第16天|二叉树前中后序迭代法遍历

递归的本质就是每一次调用时将此次参数压入栈中,在递归返回值再将参数弹出。

因此,可以使用栈来实现前中后序的迭代法遍历。

1、前序遍历-迭代法

写起来难度不大,但是主要是为空时的判断都没考虑到。

代码

犯错:

  • 两个错误都犯在了空指针的地方。需要好好反思一下
  • stack的用法不太熟练
    vector<int> preorderTraversal(TreeNode* root) {
        //法2 迭代
        vector<int> res;
        stack<TreeNode*> s;
        //注意这里若整个树为空!!
        if(root == NULL)
            return res;
        s.push(root);
        while(!s.empty()){
            TreeNode* top;
            top = s.top();
            s.pop();
            res.push_back(top->val);
            //注意这里要判断是否空!!
            if(top->right)
                s.push(top->right);
            if(top->left)
                s.push(top->left);
        } 
        return res;
    }

2、中序遍历-迭代法

不能够直接拿前序遍历的迭代法改一改。原因是前序遍历的顺序是中左右,先访问的元素是中间节点,要处理的元素也是中间节点,所以刚刚才能写出相对简洁的代码,因为要访问的元素和要处理的元素顺序是一致的,都是中间节点。

而中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的

因此,使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素

示意图:

在这里插入图片描述

代码:

注意理解思路,访问到最底层,pop时访问元素,深入右子树

    vector<int> inorderTraversal(TreeNode* root) {
        //法2 迭代法
        vector<int> res;
        stack<TreeNode*> s;
        TreeNode* cur = root;
        while(cur!=NULL || !s.empty()){
            //访问到最底层
            if(cur!=NULL){
                s.push(cur);
                cur = cur->left;
            }
            //pop时访问元素,并继续深入右子树
            else{
                //访问元素
                cur = s.top();
                s.pop();
                res.push_back(cur->val);
                //深入右子树
                cur = cur->right;
            }
        }
        return res;
    }

3、后序遍历-迭代法

思路:先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了。

反转,甚妙!!!

代码

犯错:忘记pop了,笨…

    vector<int> postorderTraversal(TreeNode* root) {
        //法1 递归
        // vector<int> res;
        // postorder(root, res);
        // return res;

        //法2 迭代,反转前序遍历
        vector<int> res;
        stack<TreeNode*> s;
        if(root == NULL)
            return res;
        s.push(root);
        while(!s.empty()){
            TreeNode* top = s.top();
            s.pop();//忘记pop了
            res.push_back(top->val);
            //这里调换了前序遍历的顺序
            if(top->left != NULL)
                s.push(top->left);
            if(top->right != NULL)
                s.push(top->right);
        }
        //反转
        reverse(res.begin(), res.end());
        return res;
    }

总结

  1. 前中后序迭代法
  2. 后序的迭代可以用前序的迭代修改后反转得到——未曾设想的思路,很神奇。
  3. stack的用法。push(), top(), pop(), empty()
  4. 反转数组reverse()函数
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值