二叉树的非递归遍历

来源:互联网 发布:外贸企业网站源码 编辑:程序博客网 时间:2024/05/14 09:02
  • 前几天数据结构课的时候,讲到二叉树的非递归遍历,老师照着严蔚敏书上的代码讲解,什么先找到最左的节点,再如何如何。。。我听得很是乱,但是我只记得之前好像在哪里看到过,其实并没有必要这么麻烦。
    我首先是写出了先序的代码,个人认为思路比严的代码要清晰。

//先序遍历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();        }    }

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

0 0
原创粉丝点击