分层遍历二叉树

1,问题一:给定一棵二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一次将单独输出一行),每一层要求访问的顺序为从左到右,并将结点依次编号。

     解法一:基本思想:用层序遍历的方法,初始化一个队列,当每一层结点进队时,统计当前层的下一层结点数目,当结点出队时,统计出队次数是不是和上一层结点数目相等,若相等,则表明上一层的结点输出完毕,换行;否则不换行打印,继续统计当前层的下一层结点数目,直到队列为空。

 

     代码如下:

  

#include "stdafx.h"
#include<stdio.h>
#include<malloc.h>
#define STACK_INCREMENT  10
#define STACK_INIT_SIZE 100
#define MAXSIZE         50
//char*ch="ABC  D  EFH  I  G  ";
//char*ch="AB  CD  E  ";
//char*ch="-+a  *b  -c  d  /e  f  ";
char*ch="124  57  8  3 6  ";
//二叉排序树的链式存储结构
typedef struct BiTNode
{
	char data;
	int count;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

//队列的链式存储结构
typedef struct QNode
{
	BiTree data;
	struct QNode *next;
}QNode,*QueuePtr;

typedef struct
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

//栈的顺序存储结构
typedef struct
{
	BiTree *base;
	BiTree *top;
	int stacksize;
}Sqstack;

//初始化一个队列,用于二叉树的层次遍历
bool InitQueue(LinkQueue&Q)
{
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
	if(!Q.front )
		exit(OVERFLOW);
	Q.front ->next =NULL;
	return true;
}

//初始化一个栈,用于二叉树的遍历
void InitStack(Sqstack&S)
{
	S.base=(BiTree*)malloc(STACK_INIT_SIZE*sizeof(BiTNode));
	if(!S.base)
		exit(0);
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
}

bool EnQueue(LinkQueue&Q,BiTree T)
{
	QueuePtr p;
	p=(QueuePtr)malloc(sizeof(QNode));
	if(!p)
		return false;
	p->data =T;
	p->next =NULL;
	Q.rear->next =p;
	Q.rear=p;
	return true;
}

bool DeleteQueue(LinkQueue&Q,BiTree &e)
{
	QueuePtr q;
	if(Q.front ==Q.rear )
		return false;
	q=Q.front->next ;
	e=q->data;
	Q.front->next=q->next ;
	if(q==Q.rear )
		Q.rear=Q.front ;
	free(q);
	return true;
}

//采用先序递归遍历创建一个二叉树
void CreateBiTree(BiTree&T)
{
	//static int n=0;//用静态变量保存上次运算结果的值。
	//char ch;
	//static char *ch="ABCD  E   F  ";
	//ch=ch+n;
	//scanf("%c",&ch);
	if(*ch==' ')
	{
		T=NULL;
		ch++;
		//n++;
		return;
	}
	else
	{
		if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))
			exit(OVERFLOW);
		T->data=*ch++;
		T->count =0;
		//n++;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
	
}


//二叉树的分层遍历算法
void LevelTraverse(BiTree T)
{
	int level[20];
	int i,j;//i表示当前层的结点数目,j表示当前层的下一层节点数目。
	int deCount;//用于记录某一层的出队次数,也就是改层的结点数。
	LinkQueue Q;
	InitQueue(Q);
	BiTree p;
	if(T)
	{
	  EnQueue(Q,T);//根结点入队
	  i=j=0;//初始时,为第一层
	  j++;//第二层
	  deCount=0;//初始时,出队次数。
	  level[0]=1;//初始时,第一层的结点数目
	  level[1]=0;//初始时,第二层的结点数目
	}
	//一次循环,完成的任务是:队头结点出队并打印;统计当前层的出队次数;累计当前层的下一层的结点数目;
	while(Q.front!=Q.rear )
	{
		DeleteQueue(Q,p);//出队
		deCount++;//出队次数加1,当前层的结点数。
		if(p->lchild )//如果当前结点的左孩子存在,下一层结点数加1
		 {
		     EnQueue(Q,p->lchild);
		     level[j]++;//统计下一层结点数目
		  }
	    if(p->rchild )//如果当前结点的右孩子存在,下一层结点数加1
		 {
		     EnQueue(Q,p->rchild);
		     level[j]++;//统计下一层结点数目
		  }
		if(deCount!=level[i])//如果当前的出队次数不等于上一层的结点数目,不换行输出
		{
		    printf("%c ",p->data);
		}
		else                
		{
			printf("%c\n",p->data);//如果当前层的出队次数等于上一层的结点数目,换行输出,
			deCount=0;             //当前层输出完毕,同时下一层统计结点数的过程也完毕,并初始化下下一层统计结点数目的参数。
		    i=j;
		    j++;
		    level[j]=0;            //当前层的下一层的初始结点数目。
		}

	}
  printf("\n");
}

void main()
{
	int length;
	BiTree BST;
	printf("*************************************************\n");
	printf("        二叉树按层次遍历算法           \n");
	printf("*************************************************\n");
	printf("输入的待建二叉树序列为:");
	printf("%s",ch);
	printf("\n");
	CreateBiTree(BST);
	printf("\n");
	printf("输出按层次遍历结果:\n");
	LevelTraverse(BST);
	printf("\n");
	free(BST);
}



运行结果如下:




 2,问题二,打印二叉树中某层次的结点(从左至右),其中根结点为第1层。

        再上一个问题的基础上,用一个判断语句:如果当前层等于要打印层,则输出,否则不输出

        注意:上一题中,else语句中打印的是某一层的最后一个结点,再换行的,所以,else中也要有个判断句,否则某一层中的最后一个结点无法输出。

   代码如下:

#include "stdafx.h"
#include<stdio.h>
#include<malloc.h>
#define STACK_INCREMENT  10
#define STACK_INIT_SIZE 100
#define MAXSIZE         50
//char*ch="ABC  D  EFH  I  G  ";
//char*ch="AB  CD  E  ";
char*ch="-+a  *b  -c  d  /e  f  ";
//char*ch="124  57  8  3 6  ";
//二叉排序树的链式存储结构
typedef struct BiTNode
{
	char data;
	int count;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

//队列的链式存储结构
typedef struct QNode
{
	BiTree data;
	struct QNode *next;
}QNode,*QueuePtr;

typedef struct
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

//栈的顺序存储结构
typedef struct
{
	BiTree *base;
	BiTree *top;
	int stacksize;
}Sqstack;

//初始化一个队列,用于二叉树的层次遍历
bool InitQueue(LinkQueue&Q)
{
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
	if(!Q.front )
		return false;
	Q.front ->next =NULL;
	return true;
}

//初始化一个栈,用于二叉树的遍历
void InitStack(Sqstack&S)
{
	S.base=(BiTree*)malloc(STACK_INIT_SIZE*sizeof(BiTNode));
	if(!S.base)
		return ;
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
}

bool EnQueue(LinkQueue&Q,BiTree T)
{
	QueuePtr p;
	p=(QueuePtr)malloc(sizeof(QNode));
	if(!p)
		return false;
	p->data =T;
	p->next =NULL;
	Q.rear->next =p;
	Q.rear=p;
	return true;
}

bool DeleteQueue(LinkQueue&Q,BiTree &e)
{
	QueuePtr q;
	if(Q.front ==Q.rear )
		return false;
	q=Q.front->next ;
	e=q->data;
	Q.front->next=q->next ;
	if(q==Q.rear )
		Q.rear=Q.front ;
	free(q);
	return true;
}

//采用先序递归遍历创建一个二叉树
void CreateBiTree(BiTree&T)
{
	//static int n=0;//用静态变量保存上次运算结果的值。
	//char ch;
	//static char *ch="ABCD  E   F  ";
	//ch=ch+n;
	//scanf("%c",&ch);
	if(*ch==' ')
	{
		T=NULL;
		ch++;
		//n++;
		return;
	}
	else
	{
		if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))
			return;
		T->data=*ch++;
		T->count =0;
		//n++;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
	
}

//计算二叉树的深度
int depth(BiTree T)
{
	int d1,d2;
	if(!T)
		return 0;
	else
	{
	d1=depth(T->lchild);
	d2=depth(T->rchild);
	return (d1>d2)?(d1+1):(d2+1);
	}

}

//二叉树的分层遍历算法
void LevelTraverse(BiTree T,int levels)
{
	int level[20];
	int i,j;//i表示当前层的结点数目,j表示当前层的下一层节点数目。
	int deCount;//用于记录某一层的出队次数,也就是改层的结点数。
	LinkQueue Q;
	InitQueue(Q);
	BiTree p;
	if(T)
	{
	  EnQueue(Q,T);//根结点入队
	  i=j=0;//初始时,为第一层
	  j++;//第二层
	  deCount=0;//初始时,出队次数。
	  level[0]=1;//初始时,第一层的结点数目
	  level[1]=0;//初始时,第二层的结点数目
	}
	//一次循环,完成的任务是:队头结点出队并打印;统计当前层的出队次数;累计当前层的下一层的结点数目;
	while(Q.front!=Q.rear )
	{
		DeleteQueue(Q,p);//出队
		deCount++;//出队次数加1,当前层的结点数。
		if(p->lchild )//如果当前结点的左孩子存在,下一层结点数加1
		 {
		     EnQueue(Q,p->lchild);
		     level[j]++;//统计下一层结点数目
		  }
	    if(p->rchild )//如果当前结点的右孩子存在,下一层结点数加1
		 {
		     EnQueue(Q,p->rchild);
		     level[j]++;//统计下一层结点数目
		  }
		if(deCount!=level[i])//如果当前的出队次数不等于上一层的结点数目,不换行输出
		{
			if(i==levels)
		    printf("%c ",p->data);
		}
		else                
		{
			if(i==levels)
			printf("%c",p->data);//如果当前层的出队次数等于上一层的结点数目,换行输出,
			deCount=0;             //当前层输出完毕,同时下一层统计结点数的过程也完毕,并初始化下下一层统计结点数目的参数。
		    i=j;
		    j++;
		    level[j]=0;            //当前层的下一层的初始结点数目。
		}

	}
  printf("\n");
}

void main()
{
	int level;
	int length;
	BiTree BST;
	printf("*************************************************\n");
	printf("             输出二叉树第n层结点的算法           \n");
	printf("*************************************************\n");
	printf("输入的待建二叉树序列为:");
	printf("%s",ch);
	printf("\n");
	CreateBiTree(BST);
	printf("\n");
	length=depth(BST);
	printf("输出此二叉树的深度为:%d\n",length);
	printf("\n");
	printf("请输入二叉树的level层(level<=%d,输出的为二叉树的第level+1层结点):",length);
	scanf("%d",&level);
	printf("\n");
	printf("输出二叉树第%d层的结点:\n",level+1);
	LevelTraverse(BST,level);
	printf("\n");
	free(BST);
}

运行结果如下:



3,问题三,输出二叉树某一层结点的数目。

     代码如下:

   

#include "stdafx.h"
#include<stdio.h>
#include<malloc.h>
#define STACK_INCREMENT  10
#define STACK_INIT_SIZE 100
#define MAXSIZE         50
//char*ch="ABC  D  EFH  I  G  ";
//char*ch="AB  CD  E  ";
char*ch="-+a  *b  -c  d  /e  f  ";
//char*ch="124  57  8  3 6  ";
//二叉排序树的链式存储结构
typedef struct BiTNode
{
	char data;
	int count;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

//队列的链式存储结构
typedef struct QNode
{
	BiTree data;
	struct QNode *next;
}QNode,*QueuePtr;

typedef struct
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

//栈的顺序存储结构
typedef struct
{
	BiTree *base;
	BiTree *top;
	int stacksize;
}Sqstack;

//初始化一个队列,用于二叉树的层次遍历
bool InitQueue(LinkQueue&Q)
{
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
	if(!Q.front )
		return false;
	Q.front ->next =NULL;
	return true;
}

//初始化一个栈,用于二叉树的遍历
void InitStack(Sqstack&S)
{
	S.base=(BiTree*)malloc(STACK_INIT_SIZE*sizeof(BiTNode));
	if(!S.base)
		return ;
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
}

bool EnQueue(LinkQueue&Q,BiTree T)
{
	QueuePtr p;
	p=(QueuePtr)malloc(sizeof(QNode));
	if(!p)
		return false;
	p->data =T;
	p->next =NULL;
	Q.rear->next =p;
	Q.rear=p;
	return true;
}

bool DeleteQueue(LinkQueue&Q,BiTree &e)
{
	QueuePtr q;
	if(Q.front ==Q.rear )
		return false;
	q=Q.front->next ;
	e=q->data;
	Q.front->next=q->next ;
	if(q==Q.rear )
		Q.rear=Q.front ;
	free(q);
	return true;
}

//采用先序递归遍历创建一个二叉树
void CreateBiTree(BiTree&T)
{
	//static int n=0;//用静态变量保存上次运算结果的值。
	//char ch;
	//static char *ch="ABCD  E   F  ";
	//ch=ch+n;
	//scanf("%c",&ch);
	if(*ch==' ')
	{
		T=NULL;
		ch++;
		//n++;
		return;
	}
	else
	{
		if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))
			return;
		T->data=*ch++;
		T->count =0;
		//n++;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
	
}

//计算二叉树的深度
int depth(BiTree T)
{
	int d1,d2;
	if(!T)
		return 0;
	else
	{
	d1=depth(T->lchild);
	d2=depth(T->rchild);
	return (d1>d2)?(d1+1):(d2+1);
	}

}

//二叉树的分层遍历算法
void LevelTraverse(BiTree T,int levels)
{
	int level[20];
	int i,j;//i表示当前层的结点数目,j表示当前层的下一层节点数目。
	int deCount;//用于记录某一层的出队次数,也就是改层的结点数。
	LinkQueue Q;
	InitQueue(Q);
	BiTree p;
	if(T)
	{
	  EnQueue(Q,T);//根结点入队
	  i=j=0;//初始时,为第一层
	  j++;//第二层
	  deCount=0;//初始时,出队次数。
	  level[0]=1;//初始时,第一层的结点数目
	  level[1]=0;//初始时,第二层的结点数目
	}
	//一次循环,完成的任务是:队头结点出队并打印;统计当前层的出队次数;累计当前层的下一层的结点数目;
	while(Q.front!=Q.rear )
	{
		DeleteQueue(Q,p);//出队
		deCount++;//出队次数加1,当前层的结点数。
		if(p->lchild )//如果当前结点的左孩子存在,下一层结点数加1
		 {
		     EnQueue(Q,p->lchild);
		     level[j]++;//统计下一层结点数目
		  }
	    if(p->rchild )//如果当前结点的右孩子存在,下一层结点数加1
		 {
		     EnQueue(Q,p->rchild);
		     level[j]++;//统计下一层结点数目
		  }
		if(deCount==level[i])
		{
		    if(i==levels)//如果等于输入的层数,则输出该层结点数目
		    printf("%d",level[i]);	
		    deCount=0;             
		    i=j;
		    j++;
		    level[j]=0; 
		}
	}
  printf("\n");
}

void main()
{
	int level;
	int number;
	int length;
	BiTree BST;
	printf("*************************************************\n");
	printf("             输出二叉树第n层结点数目的算法           \n");
	printf("*************************************************\n");
	printf("输入的待建二叉树序列为:");
	printf("%s",ch);
	printf("\n");
	CreateBiTree(BST);
	printf("\n");
	length=depth(BST);
	printf("输出此二叉树的深度为:%d\n",length);
	printf("\n");
	printf("请输入二叉树的level层(level<=%d,输出的为二叉树的第level+1层结点数目):",length);
	scanf("%d",&number);
	printf("\n");
	printf("输出二叉树第%d层的结点数目:\n",number+1);
	LevelTraverse(BST,number);
	printf("\n");
	free(BST);
}

运行结果如下:

 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值