二叉树的三种非递归遍历

递归算法和非递归算法的转换:

可以借助栈,将二叉树的递归算法转换为非递归算法,下面以中序遍历为例给出中序遍历的非递归算法。先扫描(并非访问)根结点的所有左结点并将他们一一进栈。然后出战一个结点 *p(显然结点*p没有左孩子结点或者左孩子结点均已访问过),则访问它。然后扫描该结点的有孩子结点,将其进栈在扫描该右孩子结点的所哟左结点并一一进栈,如此继续,知道栈空为止。

/*中序遍历非递归算法*/
void InOrder2(BiTree tree, void(*visit)())
{
Sqstack S;
S.top = -1;
BiTree p = tree;
while (p||!isempty(S))            //栈不空或P不空时循环
{
if (p)
{                             
push(&S, p);              //根指针进栈,遍历左子树;
p = p->lchild;             //每遇非空二叉树先向左走;
}
else
{                           
p=pop(&S,p);                   //根指针退栈,访问根结点,遍历右子树;
visit(p->data);             //退栈,访问根节点
p = p->rchild;             //再向右子树走
}
}
}

在说一下比较麻烦的后序非递归二叉树遍历算法:

算法的思想:

因为后序非递归遍历二叉树的顺序是先访问左子树,再访问右子树,最后访问根结点。当用栈来存储结点,必须分清返回的根结点时,是从左子树返回的,还是从右子树返回的。所以,使用辅助指针r,其指向最近访问过的结点。也可以在结点中增加一个标志域,记录是否已经访问过;

/*后序遍历非递归算法*/
void PostOrder2(BiTree tree, void(*visit)())
{
Sqstack S;
S.top = -1;
BiTree p = tree;
BiTree q = NULL;
BiTree r = NULL;
while (p || !isempty(S))            //栈不空或P不空时循环
{
if (p)                            
{                                  //走到最左边
push(&S, p);              
p = p->lchild;          
}
else
{
p= gettop(&S,q);                       //取栈顶点
if ((p->rchild)&&p->rchild!=r)         //如果右子树存在,且未被访问过

p = p->rchild;                   //转向右
push(&S, p);                       //压入栈
p = p->lchild;                      //在走到最左        
}
else
{
q=pop(&S, q);              //将结点弹出
visit(q->data);            // 访问该节点
r = q;                    //记录最近访问过的的结点
p = NULL;                 //结点访问完后,重置p指针
}
}
}
}

附加上先序遍历非递归算法:理解同中序类似;

/*先序遍历非递归算法*/
void PreOrder2(BiTree tree, void(*visit)())
{
Sqstack S;
S.top = -1;
BiTree p = tree;
while (p || !isempty(S))            //栈不空或P不空时循环
{
if (p)
{
push(&S, p);     
visit(p->data);
p = p->lchild;             
}
else
{
p = pop(&S, p);                                
p = p->rchild;             
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值