Leetcode 102/144/145 二叉树的前/中/后序遍历,迭代写法模板(C++)

今天在刷Leetcode的二叉树卡片,首先碰到的就是二叉树的三种遍历方法,递归方法很简单,但是要求用迭代的方法来写的话就没那么容易了,在题解区里看到了一个大神的模板化迭代写法,非常有新意,于是在这里写点自己的理解

原文链接如下:

https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/miao-sha-quan-chang-ba-hou-lang-by-sonp/

理论上来说,所有递归的算法都是可以用非递归来实现的,因为递归本身就是操作系统调用栈来保存函数的入口地址,遇到return之后返回到入口,因此用非递归方法写递归程序最核心的部分就是

1. 如何“保护现场”,在二叉树的遍历这里,原答案用到了一个nullptr空指针来保存当前访问但又不输出的那个节点(下面代码中的temp节点),也就是说,第二次遇到同一个节点的时候,意味着这个节点的前驱已经遍历过了,因此可以放心大胆地输出当前节点的value

2. 由于栈是FILO先进后出的结构,这就跟递归的顺序要相反,也就是说我们正常后序遍历的顺序是 left->right->mid,在栈这里就要mid->right->left的顺序入栈,出栈的时候才能按照正常递归的顺序

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector postorderTraversal(TreeNode* root) {
        if(!root) return {};
        vectorans;
        stackmystack;            //用栈来保存遍历的节点
        mystack.push(root);
        while(!mystack.empty())
        {
            auto temp = mystack.top();
            mystack.pop();
            if(temp)
            {
                mystack.push(temp);            //此题为后序遍历,因此入栈顺序要反过来,为中->左->右
                mystack.push(nullptr);
                if(temp->right) mystack.push(temp->right);
                if(temp->left) mystack.push(temp->left);
            }
            else
            {
                ans.push_back(mystack.top()->val);
                mystack.pop();
            }
        }
        return ans;

    }
};

上面是本人参照链接自己写的后序遍历的一个案例,先序遍历和中序遍历只需要将if(temp)里的入栈顺序作相应调整即可

 

另外此类题还有官方题解提到的莫里斯遍历,核心的部分也是确认当前节点的前驱是否已遍历,实现O(1)的空间复杂度,这里先占个坑,后面自己看懂了再来写感想

你可能感兴趣的:(LeeTCode)