二叉树利用队列实现层次遍历

这里先提一句为什么之前树的创建可以由前序遍历的方法搞定,原因是前序遍历的时候把所有的空节点都包含在内了,如果仅仅只有非空节点的前序遍历输入,是无法得到单一二叉树的,例如给出了一个前序遍历顺序AB

那么有可能是两种情况,如下图所示

     A     或者  A

B                        B

甚至给出它的后序遍历也不可以,如果得知两种遍历顺序希望获得唯一的二叉树,至少要给出其中序遍历

转回主题,如何利用队列实现层序遍历呢

队列实现:遍历从根节点开始,首先将根节点入队,然后开始执行循环:结点出队、访问该节点、其左右儿子入队

层序遍历的基本过程是:

先根节点入队,然后:

1.从队列中取出一个元素

2.访问该元素所指的结点

3.若该元素所指结点的左、右孩子结点非空,则将其左、右孩子的指针顺序入队

实现代码如下

#include "stdio.h"  
#include "stdlib.h"    

#define ERROR 0

typedef struct tree
{  
    char data;  
    struct tree *lchild;  
    struct tree *rchild;  
 }*Ptree; 

typedef Ptree ElementType;

struct Node{      
     ElementType Data;      
    struct Node *Next;      
};      
      
struct QNode{      
    struct Node *rear;      
    struct Node *front;      
};  
typedef struct QNode *Queue;    

//创建树
Ptree createTree();

//创建队列  
Queue CreateQueue();  
//删除队列头元素  
ElementType DeleteQ(Queue PtrQ);   
//在队尾插入元素  
void InsertQ(ElementType item,Queue PtrQ);  
//判断是否空    
int IsEmpty(Queue Q);  

//利用队列层次遍历
void LevelOrderTraversal(Ptree BT);


void main()  
{   
   Ptree t; 
   printf("先序创建二叉树,用空格代表虚结点:\n");
   t=createTree(); 
   printf("\n");
   printf("利用队列的层次遍历:\n");
   LevelOrderTraversal(t);
   printf("\n");
   system("pause");
}


 
//树的建立
 Ptree createTree()   
 {  
     char ch;  
     Ptree t;  
     ch=getchar();  //输入二叉树数据
     if(ch==' ')  //判断二叉树是否为空
         t=NULL;  
     else 
     {  
         t=(Ptree)malloc(sizeof(Ptree));  //二叉树的生成
         t->data=ch;  
         t->lchild=createTree();  
         t->rchild=createTree();  
     }  
     return t;  
 }  

 
//创建队列  
Queue CreateQueue(){  
    Queue PtrQ;    
    PtrQ=(Queue)malloc(sizeof(struct QNode));  
    struct Node *rear;  
    struct Node *front;  
    rear =(Node*)malloc(sizeof(struct Node));  
    rear=NULL;  
    front =(Node*)malloc(sizeof(struct Node));  
    front=NULL;  
    PtrQ->front=front;  
    PtrQ->rear=rear;  
    return PtrQ;  
};  

//删除队列头元素 
ElementType DeleteQ(Queue PtrQ){      
    struct Node *FrontCell;      
    ElementType FrontElem;      
      
    if(IsEmpty(PtrQ)){      
        printf("队列空");      
        return ERROR;      
    }    
    FrontCell=PtrQ->front;    
    if(PtrQ->front==PtrQ->rear)    
       PtrQ->front=PtrQ->rear=NULL;    
    else{    
        PtrQ->front=PtrQ->front->Next;    
    }    
      FrontElem=FrontCell->Data;    
      free(FrontCell);    
      return FrontElem;      
}      

//在队尾插入元素  
void InsertQ(ElementType item,Queue PtrQ){    
    struct Node *FrontCell;    
    FrontCell=(Node*)malloc(sizeof(struct Node));  
    FrontCell->Data=item;  
    FrontCell->Next=NULL;  
  
    if(IsEmpty(PtrQ)){  
        PtrQ->front=FrontCell;  
        PtrQ->rear=FrontCell;  
    }  
    else{  
        PtrQ->rear->Next=FrontCell;  
        PtrQ->rear=FrontCell;  
    }  
};     

//判断是否空
int IsEmpty(Queue Q){  
     return(Q->front==NULL);    
}; 



//利用队列层次遍历
void LevelOrderTraversal(Ptree BT)
{
	Queue Q;
	Ptree T;
	if(!BT) return;
	Q=CreateQueue();
	T=BT;
	InsertQ(T,Q);
	while(!IsEmpty(Q)){
		T=DeleteQ(Q);
		printf("%c",T->data);
		if(T->lchild) InsertQ(T->lchild,Q);
		if(T->rchild) InsertQ(T->rchild,Q);
	}
};
二叉树和之前的一样

                 A

       B                  C

D         F      G           I

         E             H


执行效果如下



  • 23
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉风小宇

请我喝个咖啡呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值