二叉树前、中、后序遍历的非递归形式

今天复习了一下二叉树前中后遍历的非递归形式,感觉还是蛮有意思的。并且有一定的规律,故提笔记之。

1. 前序遍历

    vector<int> preorderTraversal(TreeNode* root) {
        vector<TreeNode *> st;
        vector<int> res;
        TreeNode *cur = root;
        while(!st.empty() || cur!=nullptr){
            while(cur!=nullptr){
                res.push_back(cur->val);
                st.push_back(cur);
                cur = cur->left;
            }
            cur = st.back();
            st.pop_back();
            cur = cur->right;
        }
        return res;
    }

这里我补充一下,由于前序遍历是属于传统的深度搜索,所以它也可以写成传统的深度优先搜索的形式

    vector<int> preorderTraversal(TreeNode* root) {
        vector<TreeNode *> st;
        vector<int> res;
        st.push_back(root);
        vector<int> res;
        while(!st.empty()){
            TreeNode *cur = st.back();
            st.pop_back();
            if(cur!=nullptr)
                res.push_back(cur->val);
            else
                continue;
            
            st.push_back(cur->right);
            st.push_back(cur->left);
        }
        return res;
    }

注意:这种相对于二叉树是更加好用的而且不仅仅能用于二叉树,多叉树,以及其他任意情况的dfs都可用这个模板

2. 中序遍历

还是和前序遍历类似的模板

    vector<int> inorderTraversal(TreeNode* root) {
        vector<TreeNode *> st;
        TreeNode *cur = root;
        vector<int> res;

        while(!st.empty() || cur != nullptr){
            while(cur!=nullptr){
                st.push_back(cur);
                cur = cur->left;
            }
            cur = st.back();
            st.pop_back();
            res.push_back(cur->val);
            cur = cur->right;
        }
        return res;
    }

3. 后序遍历

还是和前序中序遍历一样的模板,但是这要难一些,因为我们在遍历完左子树后我们还得通过根节点过到右子树,且在右节点非空时,我们还得把根节点压回去,且节点出栈的时候我们要设置好条件判断是否可以输出。

** 注意这里关键在于prev指针**。这个指针保存我们上一次输出的节点。如果我们从栈顶取出的节点的右节点和prev指向的节点一样,那我们可以肯定此时从栈顶取出来的节点右子树肯定遍历完了。所以我们可以输出此时的节点;如果此时右节点为空,同样我们也可以输出此节点。

 vector<int> postorderTraversal(TreeNode* root) {
        /*尝试一下非递归*/
        vector<TreeNode *> st;
        vector<int> res;
        TreeNode *cur = root;
        TreeNode *prev = nullptr;
        while(!st.empty() || cur!=nullptr){
            while(cur!=nullptr){
                st.push_back(cur);
                cur=cur->left;
            }
            cur = st.back();
            st.pop_back();
            if(cur->right==nullptr || cur->right == prev){
                res.push_back(cur->val);
                prev =  cur;
                cur=nullptr;
            }else{
                st.push_back(cur);
                cur = cur->right;
            }
        }
        return res;
    }

总结:我们可以记一下这个模板

 		vector<TreeNode *> st;
        vector<int> res;
        TreeNode *cur = root;
        while(!st.empty() || cur!=nullptr){
            while(cur!=nullptr){
                st.push_back(cur);
                cur=cur->left;
            }
            cur = st.back();
            st.pop_back();
           /*-------------
           ----------------
           -----------
           ---------------*/
        }
        return res;

记住这个模板,我们写的时候就能很快写出来了。


今天又是收获满满的一天,加油~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值