二叉树后序非递归遍历

这里我们知道二叉树的后序遍历,是先遍历左子树,然后右子树,最后是根结点。

因此我们要先

1.找到二叉树最左边的结点,然后判断其右子树是否为空.

2.若右子树不为空,则在右子树上从步骤1开始重复执行知道右子树为空。若右子树为空,则访问该结点,然后找到结点的父亲节点,然后重复从步骤2的操作。

3.重复步骤1,2。直到全部结点都遍历完。

这里我通过图来具体解释。

这里我们找到树的最左节点D,判断D的右子树为空,则访问D结点(即打印D),然后找到D的父亲B结点。判断B的右子树不为空。则找到B结点的右子树的最左节点E。E的右子树为空。访问E结点,B结点的左右子树都访问完,访问B结点。

然后遍历A结点的右子树与左子树方法一样。

这里由于我们是非递归的方法,那么我们要如何让记录父结点(B,A)呢?

这里我们使用栈,记录在查找树最左结点的过程中经过的所有结点。

 

每访问过一个结点就将结点出栈。直到栈空为止。

这里我们以leetcode第145题为例。

这里我们直接上代码:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        TreeNode* cur=root;
        stack<TreeNode*>st;
        vector<int>s;
        while(cur||!st.empty())//特殊情况空树
        {
            while(cur)//将查找最左节点所经过的结点都放到栈里
            {
                st.push(cur);
                cur=cur->left;
            }
            TreeNode* temp=st.top()
            if(temp->right==nullptr)//最左节点的右子树为空
            {
                s.push_back(temp->val);
                st.pop();
            }
            else
            {
                cur=temp->right;//最左节点的右子树不为空,重复循环找右子树的最左节点
            }
        }
        return s;
    }
};

这里但我们提交后会发现时间超时。

这里我们可以通过一个上图的例子一个一个的带入,查找错误。这里我们会发现:

当程序会卡在B结点处。因为当第二次到B结点时,都会判断其右节点不为空。导致重复入栈。

因此我们需要想办法区分B的右子树是否入过栈。

这里我们可以通过记录上一个出栈的变量来解决(第二次到B结点时,上一个结点一定是B的右节点E)

完善代码:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        TreeNode* cur=root;
        TreeNode* prev=nullptr;
        stack<TreeNode*>st;
        vector<int>s;
        while(cur||!st.empty())
        {
            while(cur)
            {
                st.push(cur);
                cur=cur->left;
            }
            TreeNode* temp=st.top();
            if(temp->right==nullptr||prev==temp->right)
            {
                st.pop();
                s.push_back(temp->val);
                prev=temp;
            }
            else
            {
                cur=temp->right;
            }
        }
        return s;
    }
};

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
回答: 后序非递归遍历二叉树有两种方法。方法一是将后序遍历的访问顺序变成根右左,然后再逆置顺序。具体实现可以使用栈来辅助遍历,首先将根节点入栈,然后循环执行以下操作:如果栈不为空,取出栈顶节点,将其值加入结果数组,并将其右子节点入栈,再将其左子节点入栈。最后将结果数组逆置即可得到后序遍历的结果。方法二与前序遍历的方法类似,只是在访问节点时将节点值插入结果数组的头部,最后不需要逆置结果数组。具体实现可以使用栈来辅助遍历,首先将根节点入栈,然后循环执行以下操作:如果栈不为空,取出栈顶节点,将其值插入结果数组的头部,并将其左子节点入栈,再将其右子节点入栈。最后得到的结果数组就是后序遍历的结果。\[1\]\[3\] #### 引用[.reference_title] - *1* [如何使用非递归的方式后序遍历二叉树](https://blog.csdn.net/Sunny5106/article/details/119249405)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【数据结构二叉树非递归遍历](https://blog.csdn.net/qq_66314292/article/details/129038995)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慢慢走,慢慢等

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值