二叉树的非递归先序、中序、后序遍历

算法思想:
先序:NLR的访问顺序,由于R节点,即右孩子的访问需要通过根节点的指针来实现,所以,需要设一个栈来存储根节点。具体看代码:

void preorder(btree t){
 initstack(s);//初始化栈
 btree p=t;

 while(p||!empty(s)){
  if(p){//如果该节点非空
   visit(p);//访问
   push(s,p);//入栈,栈中元素全部非空
   p=p->lchild;//走到最左
  }
  else{//空节点
   pop(s,p);//退栈,栈中元素全部非空
   p=p->lchild;//转向右子树
  }
 }//while
}

中序遍历和先序遍历几乎一样:

void midorder(btree t){
 initstack(s);
 btree p=t;

 while(p||!empty(s)){
  if(p){
  push(s,p);
  p=p->lchild;
  }
  else{
  pop(s,p);
  visit(p);
  p=p->rchild;
  }
 }
}

后序遍历:LRN顺序。L和R都需要通过N的左右指针来指向,所以L和R未访问完之前,N都要放在栈内。具体为,从L返回时,N不能退栈,从R返回或R为空时,N退栈并访问。而要判断是从L返回还是后者,需要用一个指针r记录最近访问的节点来判断是从L还是R返回。

void postorder(btree t){
 initstack(s);
 btree p=t,r=null;//r记录最近访问的节点,初始化为空

 while(p||!empty(s)){
  if(p){//走到最左
   push(s,p);
   p=p->lchild;
  }
  else{//p为空
   gettop(s,p);//先获取栈顶,而不是退栈
   if(p->rchild&&p->rchild!=r){//右孩子存在且未被访问过
    //转向右子树并再走向左孩子
    p=p->rchild;
    push(s,p);
    p=p->lchild;
   }
   else{//没有右孩子或者右孩子被访问过(从右边返回)
    //退栈并访问该根节点
    pop(s,p);
    visit(p);
    r=p;//用r记录最近访问的节点
    p=null;//p置空,以防再次入栈
   }//else
  }//else
 }//while
}

后序遍历的应用:找祖先,栈顶元素以下的元素全部为其祖先。具体为,把visit部分改为:依次输出栈内元素。
若找x、y的共同祖先,假设x在y的左边,则必然先遍历到x,此时先把栈内元素复制到另一个辅助栈(x的祖先),继续遍历到y时,依次退栈并和辅助栈中的元素比较,若遇到相等的则为共同祖先。

btree conancestor(btree t,btnode *x,btnode *y){
//查找x,y的共同祖先并返回
 initstack(s);
 initstack(s1);//辅助栈
 btree p=t,r=null;

 while(p||!empty(s)){
  if(p){
   push(s,p);
   p=p->lchild;
  }
  else{
   gettop(s,p);
   if(p->rchild&&p->rchild!=r){
    p=p->rchild;
    push(s,p);
    p=p->lchild;
   }
   else{
    pop(s,p);
    if(p==x) stack s1=s;//将s栈中元素复制到辅助栈s1
    if(p==y){
     i=s1.top;
     while(p!=s1.data[i]&&i>-1)
      i--;
     if(p==s1.data[i] return p;//找到共同祖先,返回p
     pop(s,p);//没有找到,继续退栈
    }//if(p==y)
    r=p;
    p=null;
   }//else
  }//else
 }//while

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值