二叉树遍历算法

二叉树遍历算法包含: 前序, 中序, 后序, 层次遍历 共四种算法。算法

先序遍历 DLR: 先访问根节点,而后访问左子树, 最后访问右子树post

中序遍历LDR: 先访问左子树,而后根节点,最后访问右子树递归

后序遍历LRD: 先访问左子树,而后访问右子树,最后根节点队列

层次遍历: 从每层开始,至左向右逐层访问it

 

先序、中序,后序均可以使用递归方式进行访问,非递归方式使用栈辅助,  层次遍历使用队列做为辅助结构二叉树

 

1. 先序非递归遍历算法:遍历

每次递归深刻的时候,就是将左右孩子节点压栈的过程,在压栈以前,访问该节点;top

每一个节点只有在访问完右子树,或者右子树为空时,出栈,为了标志每一个节点的右孩子节点是否压栈,能够使用一个标志位flag,将节点的右孩子节点压入栈中,须要改变flag,这样每次访问栈顶元素时,若是判断右子树已访问,直接出栈;vi

 详细算法以下:while

最开始根节点入栈

while(栈非空){

1. 获取栈顶元素cur;

2. 判断该节点的flag, 若是flag为true,说明该节点右子树已经访问,出栈, 不然 访问该节点cur;

3. 若是cur有左孩子节点,压入栈中,进入step 1;

不然,若是有右孩子节点(只有右子树),压入栈中,同时修改cur的标志位flag为true;若是cur为叶子节点,直接出栈,进入step1

}

 

void preOrder(BitNode *t){

if(!t) return;

Stack<BitNode*> s;

s.push(t);

BitNode *cur=NULL;

while( !s.empty() ){

cur= s.top();

if(cur.flag){

//右子树已经访问,出栈

s.pop();

}else{

visit(cur); //访问该节点

if(cur->lchild){

s.push(cur->lchild);//访问左子树

}else{

if(cur->rchild){//访问右子树

s.push(cur->rchild);

cur->flag= true;

}else{

//叶子节点

s.pop();

}

}

}

}

}

 

2. 中序遍历非递归算法:

与先序遍历相似,只是访问完左子树后访问根节点,访问完根节点,出栈,最后访问完右子树,为了标志每一个节点的左子树是否访问,使用标志位flag

 详细算法以下:

最开始根节点入栈

while(栈非空){

1. 获取栈顶元素cur;

2. 若是cur节点标志位为flag为false, 且该节点有左子树,将左子树压入栈中,同时置该节点标志位flag为true;不然访问该节点,并出栈,若是该节点有右子树,将右孩子压入栈中

}

void inOrder(BitNode *t){

  if(!t) return;

      Stack<BitNode*> s;

      s.push(t);

      BitNode* cur=NULL;

      while( !s.empty() ){

    cur = s.top();

             if(cur->flag){

    visit(cur);

              s.pop();

            if(cur->rchild){

    s.push(cur->rchild);

    }

  }

   }//while         

}

}

 

3. 后序遍历二叉树非递归算法:

先访问左右子树,最后访问根节点,一样的,若是该节点的左右子树都已访问,直接出栈,不然更新节点的访问左右子树状态,若是状态为右子树已经访问,直接出栈

 

详细算法以下:

最开始根节点入栈

while(栈非空){

1. 获取栈顶元素cur;

2. 若是cur节点标志位为flag为2, 右子树已经访问完,访问该节点出栈, 不然,

 若是flag==1, 代表该节点左子树已经访问,开始访问右子树,若是该节点无右子树,访问该节点后直接出栈 不然,将右孩子压入栈中,同时置该节点标志位flag为2

 若是flag==0,代表该节点左右子树均未访问, 先访问左子树,若是该节点有左子树,将左子树压入栈中,同时置该节点标志位flag为1,代表左子树已经访问完, 不然判断若是该节点有右子树,将右孩子压入栈中,同时置该节点标志位flag为2,不然该节点为叶子节点,访问该节点后直接出栈

}

void postOrder(BitNode *t){

  if(!t) return;

      Stack<BitNode*> s;

      s.push(t);

      BitNode* cur=NULL;

      while( !s.empty() ){

    cur = s.top();

             if(cur->flag==2){

    visit(cur);

              s.pop();

           }else if(cur-> flag==0 ){

         if(cur->lchild){

          s.push(cur->lchild);

         cur->flag =1;

        }else{

      if(cur->rchild){

    s.push(cur->rchild);

              cur->flag=2;

    }else{

               //叶子节点

      visit(cur);

              s.pop();

            }

     }   

  }

   }//while         

}

 

4.层次遍历算法:

使用队列FIFO的特性,至左向右依次将根节点的孩子节点压入队列中

相关文章
相关标签/搜索