二叉树的非递归遍历

  //非递归算法的二叉树 前序、中序、后续查找
void preorder1(btnode *b)//前序遍历1
  {
      /*由先序遍历过程可知,先访问根节点,再遍历左子树,最后遍历右子树,由于在二叉链中左右子树是通过根结点的指针域指向的,在访问根节点后后遍历左子树会丢失右子树的节点,需要使用一个栈来临时保存左右子树的地址
         由于栈是先进后出的,而先序遍历是先遍历左子树后遍历右子树,所以当访问完一个非叶子节点后应先将右孩子进栈,再将其左孩子进栈;*/         
      btnode *p=b;
      stack<btnode>stack;
      if(b!=NULL)
      {
          stack.push(b);
          while(!stack.empty())
          {
              p=stack.pop();
              cout<<p->date<<' ';
              if(p->rchild!=NULL)
                stack.push(p->rchild);
              if(p->lchild!=NULL)
                stack.push(p->lchild);
          }
          cout<<endl;
      }
      //stack.clear();
}

void preorder2(btnode *b)//前序遍历2
{
    /*此时当前栈顶节点要么没有左子树要么左子树已经被遍历,所以转向他的右子树*/
    btnode *p=b;
    stack<btnode>stack;
    while(!stack.empty()||p!=NULL)
    {
        while(p!=NULL)//if(p!=NULL)
        {
            cout<<p->date<<' ';
            stack.push(p);
            p=p->lchild;
        }
        if(!stack.empty())//else
        {
            p=stack.pop();
            p=p->rchild;
        }
    }
    cout<<endl;
    //stack.clear();
}

//中序遍历
void inorder(btnode *b)
{
    btnode *p=b;
    stack<btnode>stack;
    while(p!=NULL||!stack.empty())
    {
        while(p!=NULL)
        {
            stack.push(p);
            p=p->lchild;
        }
        if(!stack.empty())
        {
            p=stack.pop();
            cout<<p->date<<' ';
            p=p->rchild;
        }
    }
    cout<<endl;
    //stack.clear();
}

void postorder(btnode *b)//后序遍历
{
    /*后序遍历算法中即使栈顶节点的左子树已经遍历或者为空,仍然还不能访问节点p,因为他们的右子树没有遍历,只有当这样的p节点右子树已经遍历完之后才能遍历节点p
     那么需要解决2个问题,一是如何判断处理当前结点是栈顶节点,这儿设置了一个bool变量,开始置flag为true,表示访问的是站定节点,一旦转向处理右子树节点则置false
     还有一个是判断当前访问的节点的右子树是否已经被访问过(或者右子树为空),如果访问过则可以访问当前的节点,
     为此设置一个指针变量r,初始值为NULL,让他指向刚刚被访问过的节点,对于正在处理的节点,若p->rchild=r;则p的左右节点都被访问过了。*/
    btree *p=b;
    do
    {
        while(p!=NULL)
        {
            stack.push(p);
            p=p->lchild;
        }
        bool flag=true;//表示当前访问的是栈顶节点
        btnode *r=NULL;//表示当前访问的节点的上一个节点是r,(r是刚刚被访问过的节点)
        while(!stack.empty()&&true)
        {
            p=stack.top();
            if(p->rchild==r)
            {
                stack.pop();
                cout<<p->date;
                r=p;//r指向当前被访问过的节点
            }    
            else
            {
                p=p->rchild;
                flag=false;
            }
         }
    }while(!=stack.empty())
    //stack.clear();
}
http://www.cnblogs.com/liuamin/p/6383315.html
/*采用二叉链的存储结构,设计算法输出从根节点到叶子结点的逆序列,,
采用后序遍历的方法实现*/

void psotbtree(btree *b)
{
    stack<*btree>stack;
    btree *p=b;
    do
    {
        while(p!=NULL)
        {
            stack.push(p);
            p=p->lchild;
        }
        bool flag=true;
        btree *r=NULL;
        while(!stack.empty&&flag)
        {
            p=stack.top();
            if(p->rchild==r)
            {
                if(p->rchild==NULL&&p->lchild==NULL)
                    //定义一个迭代器,输出栈中的所有元素
                
                stack.pop();
                r=p;
            }
            else
            {
                p=p->rchild;
                flag=true;
            }
        }
    }while(!stack.empty())
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值