C语言二叉树的层次遍历

二叉树的层次遍历



前言

算法思想:一般的二叉树层次遍历是自上而下,从左到右,这里的遍历顺序则恰好相反。利用原有的层次遍历算法,出队的同时将各个结点指针入栈,在所有结点入栈之后再从栈顶开始依次访问所有结点直到栈为空,就结束。


一、树和队列的结构

typedef struct Node									//定义树的结构,别名为Node
{
	char data;										//数据域char类型
	struct Node* Lchild;							//左孩子
	struct Node* Rchild;							//右孩子
}Node;

typedef struct Queue								//定义队列的结构
{
	Node* data;										//data定义为Node类型的指针,因为后续的入队和出队操作使用指针取地址的方便
	struct Queue* pre;								//队列Q的前指针
	struct Queue* next;								//队列Q的后指针
}Queue;

二、对队列和树的操作

1.创建二叉树

代码如下(示例):

void creatTree(Node** tree, char* data, int* index)	//创建树,这里可能不会说很清楚,可观看上一篇博客
{
	char temp;										//temp变量进行保存
	temp = data[*index];							//保存data里面index索引值的数据
	*index += 1;									//对指针指向的数据进行++
	if (temp == '#')								//如果是#
	{
		*tree = NULL;								//该树的节点指向NULL
	}
	else
	{
		*tree = (Node*)malloc(sizeof(Node));		//如果有数据则开辟空间
		(*tree)->data = temp;						//这里需要对下一个data数据进行操作,传进来的二级指针需要加个括号来进行对data取值
		creatTree(&((*tree)->Lchild),data,index);	//使用递归的方法来进行对左孩子的创建
		creatTree(&((*tree)->Rchild), data, index);	//使用递归的方法来进行对右孩子的创建
	}
}

2.队列初始化

代码如下(示例):

Queue* initQueue()									//初始化队列
{
	Queue* Q = (Queue*)malloc(sizeof(Queue));		//开辟一个Q的空间
	Q->data = NULL;									//data指向NULL
	Q->next = Q;									//Q的next指针指向Q
	Q->pre = Q;										//Q的pre指针指向Q
	return Q;
}

3.队列初始化

代码如下(示例):

Queue* initQueue()									//初始化队列
{
	Queue* Q = (Queue*)malloc(sizeof(Queue));		//开辟一个Q的空间
	Q->data = NULL;									//data指向NULL
	Q->next = Q;									//Q的next指针指向Q
	Q->pre = Q;										//Q的pre指针指向Q
	return Q;
}

4.队列入队

代码如下(示例):

void enQueue(Node* tree, Queue* Q)					//入队,这里使用的是尾插法来进行入队
{
	Queue* node = (Queue*)malloc(sizeof(Queue));	//额外开辟一个node的节点
	node->data = tree;								//node的data指针指向传进来的tree
	node->next = Q;									//node的NEXT指向Q
	node->pre = Q->pre;								//node的pre指向Q的pre,也就是node的pre指向Q的最后一个指针
	Q->pre->next = node;							//Q的pre的next指向node,即最后的节点的next指向node
	Q->pre = node;									//Q的pre指针指向node
}	
}

5.队列出队

代码如下(示例):

Queue* deQueue(Queue* Q)							//出队
{
	if (isEmpty(Q))									//先判断是否为空
	{
		return NULL;
	}
	else
	{
		Queue* node = Q->next;						//定义一个node来指向Q的next,取得第一个节点
		Q->next->next->pre = Q;						//Q的下一个的下一个节点的pre指向Q
		Q->next = Q->next->next;					//Q的next指向Q的next的next也就是第二节点
		return node;	
	}
}

6.层次遍历

代码如下(示例):

void tree_Level(Node* tree, Queue* Q)				//层次遍历的主函数
{
	enQueue(tree,Q);								//先对根节点的入队
	while (!isEmpty(Q))								//先进行对Q队列是否为空,类似于套娃一样的
	{		
		Queue* node = deQueue(Q);					//创建一个类型为Queue的Node节点接收出队的指针
		printf("%c", node->data->data);				//因为这里的data是指针所以还需要对data指向的data取值
		if (node->data->Lchild)						//如果node的data指针指向的左孩子有值的话,再进行入队
		{
			enQueue(node->data->Lchild, Q);			//入队
		}
		if (node->data->Rchild)						//如果node的data指针指向的右孩子有值的话,再进行入队
		{
			enQueue(node->data->Rchild, Q);			//入队
		}
	}
}

总结

上述有错误的东西,麻烦请指出,谢谢啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

乐乐小工厂

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值