二叉树的非递归遍历

  • 前几天数据结构课的时候,讲到二叉树的非递归遍历,老师照着严蔚敏书上的代码讲解,什么先找到最左的节点,再如何如何。。。我听得很是乱,但是我只记得之前好像在哪里看到过,其实并没有必要这么麻烦。
    我首先是写出了先序的代码,个人认为思路比严的代码要清晰。

//先序遍历
S.push (m_root);
while(!S.empty())
    {
        p = S.top();
        S.pop();
        visit(p->data);
        if(p->rchild)
            S.push(p->rchild);
        if(p->lchild)
            S.push(p->lchild);
    }
  • 然后我就开始思考中序,发现并不那么简单,就先做后序了。后序遍历的时候,只要把弹出来的节点,依次压入另一个栈中,便可以实现了。
//另开栈的后序遍历
S.push (m_root);
while(!S.empty())
    {
        p = S.top();
        S.pop();
        P.push(p);
        if(p->lchild)
            S.push(p->lchild);
        if(p->rchild)
            S.push(p->rchild);
    }
    while(!P.empty())
    {
        visit(P.top()->data);
        P.pop();
    }
  • 先序与后序好做,是因为我们知道什么时候访问弹出的节点,先序的话,当然是立刻访问,后序的话,就算要求最后访问,我们压到栈里就好了。可是中序的时候,我没办法知道什么时候他的左子树已经访问完了。所以我参考了一下老师的代码,发现可以用一个NULL来做标识,当访问到NULL的时候,便说明下一个节点的左子树已经访问完了,那么久可以访问了。既然这样,后序遍历时也没必要重新开一个栈了。
//中序遍历
S.push (m_root);
    while(!S.empty())
    {
        p = S.top();
        S.pop();
        if(p)
        {
            if(p->rchild)
                S.push(p->rchild);
            S.push(p);
            S.push(NULL);
            if(p->lchild)
                S.push(p->lchild);
        }
        else
        {
            visit(S.top()->data);
            S.pop();

        }
    }
//不用另开栈的后序遍历
S.push (m_root);
    while(!S.empty())
    {
        p = S.top();
        S.pop();
        if(p)
        {
            S.push(p);
            S.push(NULL);
            if(p->rchild)
                S.push(p->rchild);
            if(p->lchild)
                S.push(p->lchild);
        }else
        {
            visit(S.top()->data);
            S.pop();
        }
    }

我只测试了几组数据,暂时都还是正确的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值