二叉树先中后序遍历的递归实现与非递归实现

递归实现

typedef struct BiTNode
{
    char data;
    BiTNode *lc, *rc;
} BiTNode, *BiTree;


/*先序遍历*/
void PreOrderTraverse(const BiTree T)
{
    if (T)
        cout << T->data;
    else
        return;
    PreOrderTraverse(T->lc);
    PreOrderTraverse(T->rc);
}

/*中序遍历*/
void InOrderTraverse(const BiTree T)
{
    if (T == NULL)
        return;
    InOrderTraverse(T->lc);
    cout << T->data;
    InOrderTraverse(T->rc);
}

/*后序遍历*/
void PostOrderTraverse(const BiTree T)
{
    if (T == NULL)
        return;
    PostOrderTraverse(T->lc);
    PostOrderTraverse(T->rc);
    cout << T->data;
}

非递归实现

typedef struct BiTNode
{
    char data;
    BiTNode *lc, *rc;
} BiTNode, *BiTree;

/*先序遍历*/
void PreOrderTraverse(const BiTree T)
{
    stack<BiTree> s;
    BiTree p = T;
    while (p || !s.empty())
    {
        if (p)
        {
            cout << p->data;
            s.push(p);
            p = p->lc;
        }
        else
        {
            p = s.top();
            s.pop();
            p = p->rc;
        }
    }
}

/*中序遍历*/
void InOrderTraverse(const BiTree T)
{
    stack<BiTree> s;
    BiTree p = T;
    while (p || !s.empty())
    {
        if (p)
        {
            s.push(p);
            p = p->lc;
        }
        else
        {
            p = s.top();
            s.pop();
            cout << p->data;
            p = p->rc;
        }
    }
}

/*后序遍历*/
void PostOrderTraverse(const BiTree T)
{
	stack<BiTree> s;
    BiTree p = T;
    BiTree q = NULL;
    while (p || !s.empty())
    {
        if (p)
        {
            s.push(p);
            p = p->lc;
        }
        else
        {
            p = s.top();
            if (p == q)
            {
                cout << p->data;
                s.pop();
                p = NULL;
                if (!s.empty() && s.top()->rc == q)
                    q = s.top();
            }
            else
            {
                q = p;
                p = p->rc;
            }
        }
    }
}

对非递归遍历实现的理解:

非递归实现实际上是对递归的深刻理解后得出的,首先看先序遍历和中序遍历的非递归实现,cout是访问过程,而s.push(p),p=p->lc,两句话相当于以p->lc为参数调用递归函数。仔细观察这个过程发现完全是在模拟递归函数的调用,调用递归函数时指令地址和函数参数入栈,s.push(p),p=p->lc执行完成再重新开始循环时,与以调用p->lc为参数的函数具有相同的行为。当从栈中弹出p,则相当于回到原函数中。与递归不同的是,当我们发现p为NULL时直接将栈顶元素弹出,这是因为先序和中序遍历已经完成了对栈顶元素的访问,不需要等到其调用完右子树递归再弹出。
而后序遍历则稍微复杂一些,由于后序遍历需要完成对其左子树和右子树的遍历后再访问该节点,于是用一个节点变量来记录最近已经完成左右子树遍历的节点。当从栈顶取出的元素完成左右子树的遍历后则将其从栈中弹出并访问。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值