【练习】二叉树的遍历

1.按层遍历

void oper(ChainBinTree *p) //操作二叉树结点数据 
{
     printf("%c ",p->data); //输出数据
     return;
}

void BinTree_Level(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //按层遍历 
{
     ChainBinTree *p;
     ChainBinTree *q[QUEUE_MAXSIZE]; //定义一个顺序栈 
     int head=0,tail=0;//队首、队尾序号 
     if(bt)//若队首指针不为空     
     {
         tail=(tail+1)%QUEUE_MAXSIZE;//计算循环队列队尾序号 
         q[tail] = bt;//将二叉树根指针进队
     }
     while(head!=tail) //队列不为空,进行循环 
     {
         head=(head+1)%QUEUE_MAXSIZE; //计算循环队列的队首序号 
         p=q[head]; //获取队首元素 
         oper(p);//处理队首元素 
         if(p->left!=NULL) //若结点存在左子树,则左子树指针进队 
         {
             tail=(tail+1)%QUEUE_MAXSIZE;//计算循环队列的队尾序号 
             q[tail]=p->left;//将左子树指针进队 
         }

         if(p->right!=NULL)//若结点存在右孩子,则右孩子结点指针进队 
         {
             tail=(tail+1)%QUEUE_MAXSIZE;//计算循环队列的队尾序号 
             q[tail]=p->right;//将右子树指针进队 
         }
     }
     return; 
}

  在整个队列的处理中,首先从根节点开始,将每层的结点逐步进入队列,这样就可以得到按层遍历的效果。


2.递归遍历二叉树

先序遍历

void BinTree_DLR(ChainBinTree *bt,void (*oper)(ChainBinTree *p))  //先序遍历 
{     
     if(bt)//树不为空,则执行如下操作 
     {
         oper(bt); //处理结点的数据 
         BinTree_DLR(bt->left,oper);
         BinTree_DLR(bt->right,oper);
     }
     return; 
}

中序遍历

void BinTree_LDR(ChainBinTree *bt,void(*oper)(ChainBinTree *p))  //中序遍历 
{
     if(bt)//树不为空,则执行如下操作 
     {
         BinTree_LDR(bt->left,oper); //中序遍历左子树
         oper(bt);//处理结点数据 
         BinTree_LDR(bt->right,oper); //中序遍历右子树/
     }
     return; 
} 

后序遍历

void BinTree_LRD(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //后序遍历
{
     if(bt)
     {
         BinTree_LRD(bt->left,oper); //后序遍历左子树 
         BinTree_LRD(bt->right,oper); //后序遍历右子树/
         oper(bt); //处理结点数据
     }
     return; 
}

3.非递归遍历二叉树

  利用栈可以实现遍历二叉树的非递归算法。

先序遍历

void PreOrderTraverse2(BiTree T)
/*先序遍历二叉树的非递归实现*/
{
    BiTree stack[MaxSize];              /*定义一个栈,用于存放结点的指针*/
    int top;                            /*定义栈顶指针*/
    BitNode *p;                         /*定义一个结点的指针*/
    top=0;                          /*初始化栈*/
    p=T;
    while(p!=NULL||top>0)
    {
        while(p!=NULL)                  /*如果p不空,访问根结点,遍历左子树*/
        {
            printf("%2c",p->data);          /*访问根结点*/
            stack[top++]=p;                 /*将p入栈*/
            p=p->lchild;                /*遍历左子树*/
        }
        if(top>0)                       /*如果栈不空*/
        {
            p=stack[--top];                 /*栈顶元素出栈*/
            p=p->rchild;                    /*遍历右子树*/
        }
    }
}

中序遍历

void InOrderTraverse2(BiTree T)
/*中序遍历二叉树的非递归实现*/
{
    BiTree stack[MaxSize];              /*定义一个栈,用于存放结点的指针*/
    int top;                            /*定义栈顶指针*/
    BitNode *p;                         /*定义一个结点的指针*/
    top=0;                          /*初始化栈*/
    p=T;
    while(p!=NULL||top>0)
    {
        while(p!=NULL)                  /*如果p不空,访问根结点,遍历左子树*/
        {
            stack[top++]=p;                 /*将p入栈*/
            p=p->lchild;                /*遍历左子树*/
        }
        if(top>0)                       /*如果栈不空*/
        {
            p=stack[--top];                 /*栈顶元素出栈*/
            printf("%2c",p->data);          /*访问根结点*/
            p=p->rchild;                    /*遍历右子树*/
        }
    }
}

后序遍历

void PostOrderTraverse2(BiTree T)
/*后序遍历二叉树的非递归实现*/
{
    BiTree stack[MaxSize];              /*定义一个栈,用于存放结点的指针*/
    int top;                            /*定义栈顶指针*/
    BitNode *p,*q;                      /*定义结点的指针*/
    top=0;                              /*初始化栈*/
    p=T,q=NULL;                         /*初始化结点的指针*/
    while(p!=NULL||top>0)
    {
        while(p!=NULL)                      /*如果p不空,访问根结点,遍历左子树*/
        {
            stack[top++]=p;                 /*将p入栈*/
            p=p->lchild;                    /*遍历左子树*/
        }
        if(top>0)                           /*如果栈不空*/
        {
            p=stack[top-1];                     /*取栈顶元素*/
            if(p->rchild==NULL||p->rchild==q)   /*如果p没有右孩子结点,或右孩子结点已经访问过*/
            {
                printf("%2c",p->data);          /*访问根结点*/
                q=p; 
                p=NULL; 
                top--;      
            }
            else
                p=p->rchild;
        }
    }
}
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值