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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BuptZhengChaoJie/article/details/53149454

二叉树先序遍历算法

//递归
Status PreOrderTraverse1(BiTree T)
{     if  (T)  {
           if ( visit(T->data) ) {
               if (T->lchild) 
                  if  ( ! PreOrderTraverse1(T->lchild) ) return ERROR;
               if (T->rchild)
                  if  (! PreOrderTraverse1(T->rchild) )  return ERROR;
               return OK;
           }else return ERROR;
       }else return OK; 
} //PreOrderTraverse1

//非递归
void PreOrderWithoutRecursion1(BTNode* root)
{
    if (root == NULL)
        return;
    BTNode* p = root;
    stack<BTNode*> s;
    while (!s.empty() || p)
    {
        //边遍历边打印,并存入栈中,进入右子树
        while (p){
            visit(p->data);
            s.push(p);
            p = p->lchild;
        }
        //当p为空时,说明根和左子树都遍历完了,该进入右子树了
        p = s.top();
        s.pop();
        p = p->rchild;
    }
    cout << endl;
}
void PreOrderWithoutRecursion2(BTNode* root)
{
    if (root == NULL)
        return;
    BTNode* p = root;
    stack<BTNode*> s;
    while (!s.empty() || p)
    {
        if (p){
            visit(p->data);
            s.push(p);
            p = p->lchild;
        }
        else{
            p = s.top();
            s.pop();
            p = p->rchild;
        }
    }
    cout << endl;
}

二叉树中序遍历算法

//递归
Status  InOrderTraverse(BiTree T, Status(* Visit)(TElemType e))
{   if  (T){   
        if  ( InOrderTraverse(T->lchild, Visit) )
            if ( Visit(T->data) )
                if   ( InOrderTraverse(T->rchild,Visit) )  
                    return OK;
        return ERROR;
    }else 
        return OK; 
} //InOrderTraverse

//中序遍历
void InOrderWithoutRecursion1(BTNode* root)
{
    //空树
    if (root == NULL)
        return;
    //树非空
    BTNode* p = root;
    stack<BTNode*> s;
    while (!s.empty() || p)
    {
        //一直遍历到左子树最下边,边遍历边保存根节点到栈中
        while (p){
            s.push(p);
            p = p->lchild;
        }
        //当p为空时,说明已经到达左子树最下边,这时需要出栈了
        p = s.top();
        s.pop();
        visit(p->data);
        //进入右子树,开始新的一轮左子树遍历
        p = p->rchild;
    }
}
//中序遍历
void InOrderWithoutRecursion2(BTNode* root)
{
    //空树
    if (root == NULL)
        return;
    //树非空
    BTNode* p = root;
    stack<BTNode*> s;
    while (!s.empty() || p)
    {
        if (p){
            s.push(p);
            p = p->lchild;
        }
        else{
            p = s.top();
            s.pop();
            cout << setw(4) << p->data;
            p = p->rchild;
        }
    }
}

二叉树后序遍历

//递归
Status PostOrderTraverse(BiTree T,Status(* Visit)(TElemType e))
{
    if  (T)
    {   
        if  ( PostOrderTraverse(T->lchild, Visit) )
            if   ( PostOrderTraverse(T->rchild, Visit) )
                if ( Visit(T->data) )    
                    return OK;
        return ERROR;
    }else 
        return OK; 
} //PostOrderTraverse
//非递归
//后序遍历
void PostOrderWithoutRecursion(BTNode* root)
{
    if (root == NULL)
        return;
    stack<BTNode*> s;
    //pCur:当前访问节点,pLastVisit:上次访问节点
    BTNode* pCur, *pLastVisit;
    //pCur = root;
    pCur = root;
    pLastVisit = NULL;
    //先把pCur移动到左子树最下边
    while (pCur)
    {
        s.push(pCur);
        pCur = pCur->lchild;
    }
    while (!s.empty())
    {
        //走到这里,pCur都是空,并已经遍历到左子树底端(看成扩充二叉树,则空,亦是某棵树的左孩子)
        pCur = s.top();
        s.pop();
        //一个根节点被访问的前提是:无右子树或右子树已被访问过
        if (pCur->rchild == NULL || pCur->rchild == pLastVisit)
        {
            cout << setw(4) << pCur->data;
            //修改最近被访问的节点
            pLastVisit = pCur;
        }
        /*这里的else语句可换成带条件的else if:
        else if (pCur->lchild == pLastVisit)//若左子树刚被访问过,则需先进入右子树(根节点需再次入栈)
        因为:上面的条件没通过就一定是下面的条件满足。仔细想想!
        */
        else
        {
            //根节点再次入栈
            s.push(pCur);
            //进入右子树,且可肯定右子树一定不为空
            pCur = pCur->rchild;
            while (pCur)
            {
                s.push(pCur);
                pCur = pCur->lchild;
            }
        }
    }
    cout << endl;
}
Status PostOrderTraverse1(BiTree T)
{   InitStack(S);  Push (S,{T,0});   //根结点(指针、mark)入栈
    while(!StackEmpty(S))  {    Pop(S,a);
        switch(a.mark){
        case 0:   Push(S,{a.p, 1}); //修改mark域
            if(a.p->lchild) Push(S,{a.p->lchild,0}); //访问左子树
                       break;
        case 1:    Push(S,{a.p,2}); //修改mark域
                       if(a.p->rchild) Push(S,{a.p->rchild,0}); //访问右子树
                       break;
        case 2:    if  (!visit( a.p->data)) return ERROR;
            }
    }  
    return OK;
}//PostOrderTraverse1

二叉树按层次遍历算法

Status  LevelOrderTraverse(BiTree T, Status(* Visit)(TElemType e))
{   if (T)  {
             InitQueue(Q);
             EnQueue(Q, T);         //根结点的指针T入队列
             while ( ! QueueEmpty (Q) )
             {    DeQueue(Q, p);  //从队头取一个指针
                   if ( !Visit(p->data) )   return ERROR; 
                   if (p->lchild)  EnQueue(Q, p->lchild);
                   if (p->rchild)  EnQueue(Q, p->rchild);
             }
     }
     return OK;
} //LevelOrderTraverse

猜你喜欢

转载自blog.csdn.net/BuptZhengChaoJie/article/details/53149454