用C语言借助一个队列实现二叉树层序遍历,包括二叉树与队列的结构定义,基本操作的实现。
所谓二叉树层序遍历,即从二叉树根结点开始,按从上到下、从左到右的顺序访问每一个结点。每个结点只访问一次。
#include <stdio.h>
#include <stdlib.h>
/**
* 二叉树二叉链表之非递归遍历:层序遍历
* 算法思想:借助一个队列;根树进队;队不为空时循环“从队列中出一个树p,访问该树根结点;
* 若它有左子树,左子树进队;若它有右子树,右子树进队。”
* (保证了元素进队顺序是从树的上层到下层,且同层元素在队列中从左到右相邻)
* (注:为了节约空间,这里的树进队,是指树的地址进队,而不是树结点进队,队列中存放的是对各树地址的引用)
*/
#define OK 1;
#define TURE 1;
#define FALSE 0;
#define ERROR 0;
const int OVERFLOW = -2;
const int MAXSIZE = 100;
typedef int Status;
typedef char TElemType;
//二叉链表结构定义
typedef struct BiNode{
TElemType data;
struct BiNode *lchild, *rchild;
} BiNode, *BiTree;
//顺序循环队列定义
typedef struct {
BiTree *base; //存放树型指针
int front; //头指针,若队列不为空,指向队列头元素
int rear; //尾指针,若队列不为空,指向队列尾元素的下一个位置
} SqQueue;
//由字符序列创建二叉树
Status CreateBiTree(BiTree *tree,TElemType data[],int *j,int len){
if((*j)<=len-1){
if(data[(*j)]=='#'){
(*tree)=NULL;
(*j)++;
} else {
(*tree)=(BiTree)malloc(sizeof(BiNode));
if(!(*tree)) return OVERFLOW;
(*tree)->data=data[(*j)]; //生成根结点
(*j)++;
CreateBiTree(&((*tree)->lchild),data,j,len); //构造左子树
CreateBiTree(&((*tree)->rchild),data,j,len); //构造右子树
}
}
return OK;
}
//访问二叉树结点
Status Visit(BiTree tree){
printf("%c",tree->data);
return OK;
}
//借助队列实现二叉链表的层序遍历
Status LevelOrder_ByQueue(BiTree tree) {
BiTree p;
SqQueue queue1;
InitQueue(&queue1);
EnQueue(&queue1,tree); //根结点入队
while(queue1.front!=queue1.rear){ //队不为空
DeQueue(&queue1,&p); //根节点出队
Visit(p);
if(p->lchild!=NULL) EnQueue(&queue1,p->lchild); //有左孩子就进队
if(p->rchild!=NULL) EnQueue(&queue1,p->rchild); //有右孩子也进队
}
return OK;
}
/***用到队列的相关函数***/
//循环队列初始化
Status InitQueue(SqQueue *queue) {
queue->base=(BiTree*)malloc(sizeof(BiTree)*MAXSIZE); //分配队列数组空间
if(!queue->base) return OVERFLOW; //分配失败
queue->front=0;
queue->rear=0;
return OK;
}
//循环队列入队操作
Status EnQueue(SqQueue *queue,BiTree elem){
if((queue->rear+1)%MAXSIZE==queue->front){ //队满
return ERROR;
} else {
queue->base[queue->rear]=elem;
queue->rear=(queue->rear+1)%MAXSIZE;
return OK;
}
}
//循环队列出队操作
Status DeQueue(SqQueue *queue,BiTree *elem){
if(queue->front==queue->rear){ //队空
return ERROR;
} else {
(*elem)=queue->base[queue->front];
queue->front=(queue->front+1)%MAXSIZE;
return OK;
}
}
int main(void){
//示例二叉树的结构
/*
A
/
B
/ \
C D
/ \
E F
\
G
*/
//指向二叉树的指针
BiTree bitree1;
//创建二叉树 待用数据
TElemType data1[]={'A','B','C','#','#','D','E','#','G','#','#','F','#','#','#',}; //先序遍历序列
int len1=sizeof(data1)/sizeof(data1[0]);
int* j1=(int*)malloc(sizeof(int));
*j1=0;
//按先序遍历序列创建二叉树
Status createBiTreeResult = CreateBiTree(&bitree1,data1,j1,len1);
printf("二叉树创建结果:%d\n",createBiTreeResult);
//层序遍历二叉树
Status levelOrder_ByQueue = LevelOrder_ByQueue(bitree1); //注:这里参数是二叉树根结点,而不是指针
printf("\n层序遍历二叉树结果:%d\n",levelOrder_ByQueue);
printf("\nEND");
return 0;
}