关于二叉树的多种遍历算法

1.递归法进行先根中根后根遍历

(1)先根遍历

void PreOrder(node *p)
{
    if(p!=NULL)
   {
     cout<<p->data;
     PreOrder(p->left);
     PreOrder(p->right);
    }
}
(2)中根遍历

void InOrder(node *p)
{
   if(p!=NULL)
   {
      InOrder(p->left);
      cout<<p->data;
      InOrder(p->right); 
   }
} 
(3)后根遍历

void PostOrder(node *p)
{
  if(p!=NULL)
    {
    PostOrder(p->left);
    PostOrder(p->right);     
    cout<<p->data; 
    }
}
2.非递归算法遍历,利用栈

(1)先根遍历:

void PreOrder(node *p,stack s)
{
       makeNull(s);
       while(p!=NULL)
       {
          push(p,s);
          node *temp=top(s);
          cout<<temp->data;
          pop(s);
         if(temp->rihgt)
          {
              push(temp->right);
           }
         if(temp->left)
          {
                push(temp->left);
          }
        } 
}


(2)中根遍历:

void InOrder(node *p)
{
   Stack S;
   node *h;
   h=p;
   while(h!=NULL||S!=NULL)
   {
    if(h!=NULL)
     {
       push(h,s);
       h=h->left;//找到最左的儿子,即最先输出的结点
     }
    else
     {
       h=Top(s);
       Pop(s);//左儿子空时输出该结点
       cout<<h->data;
       h=h->right;//找该结点的右儿子
     }
   }
}
(3)后根遍历(比较麻烦, 需要在节点的结构体中再加入一个参数isVisited,表示某个节点是否被访问过。思路如下:首先根节点入栈,然后判断左孩子是否为空,若不为空,则左孩子入栈,并移动node到左孩子,直到左孩子为空。然后判断栈顶元素,如果栈顶元素没有右孩子或者右孩子已经被访问过,那么就访问该栈顶元素,并出栈;如果栈顶元素有右孩子并且右孩子没有被访问过,那么把右孩子入栈,把node指针指向右孩子。
void PostOrder(node *p,stack s)
{
   makenull(s);
   push(p,s);
 while(s!=NULL)
 {
   while(p->left!=NULL)  
   {
    push(p,s);
    p=p->left;
   }
   node *temp=top(s);
   if(temp->right==NULL||temp->right->isVisited==true)
     {
       cout<<temp->data;
       temp->isVisited=true;
       pop(s);
      }
   else if(temp->right!=NULL&&tetmp->right->isVisited==false)
     { 
       push(temp->right,s);
       temp->temp->right;
     }
 }
}

3.层序遍历(需要用到队列)

非递归法:

void printTree(BinaryTree* arr[])
{
    queue<BinaryTree*> rel; //定义一个队列,数据类型是二叉树指针,不要仅是int!!不然无法遍历
    rel.push(arr[0]);
    while (!rel.empty())
    {
        BinaryTree* front = rel.front();
        printf("%d\n", front->data);
        rel.pop();                  //删除最前面的节点
        if (front->left != nullptr) //判断最前面的左节点是否为空,不是则放入队列
            rel.push(front->left);  
        if (front->right != nullptr)//判断最前面的右节点是否为空,不是则放入队列
            rel.push(front->right);
    }
}



递归法:
    void LevelOrder(queue<Node *> &nodeQueue) //已在主函数中将链表的第一个结点入列了
     {  
   
   
  1.     if (nodeQueue.empty())  
  2.     {  
  3.         return;  
  4.     }  
  5.   
  6.     Node *frontNode = nodeQueue.front();  
  7.     cout << frontNode->element << " ";  
  8.     nodeQueue.pop();  
  9.     if (frontNode->lChild != NULL)  
  10.     {  
  11.         nodeQueue.push(frontNode->lChild);  
  12.     }  
  13.     if (frontNode->rChild != NULL)  
  14.     {  
  15.         nodeQueue.push(frontNode->rChild);  
  16.     }  
  17.   
  18.     LevelOrder(nodeQueue);  





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值