实现二叉树的层次遍历、先序遍历、中序遍历、后序遍历

这篇文章展示了如何使用C语言编程实现二叉树的层次遍历。它定义了二叉树节点和队列节点的数据结构,提供了队列初始化、插入以及访问节点值的函数。此外,还包含了二叉树的创建、先序、中序、后序遍历的函数。最后,通过一个测试函数`testT()`演示了整个层次遍历的过程。
摘要由CSDN通过智能技术生成
#include <stdio.h>
#include <malloc.h>
#define MAX 100;

/*层次遍历: 利用 队列 按照 层次遍历 的顺序  来存储二叉树的结点地址,以此来实现层次遍历二叉树*/




//二叉树的结点定义
typedef struct BitNode 
{
	int data;
	struct BitNode* lchild;
	struct BitNode* rchild;

}BitNode,* BiTree;


//队列的结点定义,该队列用来存储 层次遍历 顺序的 每个二叉树结点的地址
typedef struct LinkNode
{
	BitNode* node;
	struct LinkNode* next;
}LinkNode;

//一整条队列的定义:唯一标识一条队列的是该队列的 队头 和 队尾

typedef struct QueueLink
{
	LinkNode* head;//队头
	LinkNode* rear;//队尾

}QueueLink,* QLink;

//队列初始化
void Init_QLink(QLink &QL)//头结点不存放东西
{
	QL->head = (LinkNode*)malloc(sizeof(LinkNode));
	QL->rear = QL->head;

}
//队列:先进先出(尾进头出)
//插入队列元素(尾插法)
void insert_QueueLink_rear(QLink &QL,BitNode* N)
{
	//if (N != NULL)
	//{
		LinkNode* Lnode = (LinkNode*)malloc(sizeof(LinkNode));

		Lnode->node = N;
		QL->rear->next = Lnode;
		QL->rear = Lnode;
		QL->rear->next = NULL;

		//printf("\n插入队列元素 %d 成功!", N->data);
	//}
}
//访问并打印QL->head所指向的队列节点的二叉树结点的数值
void visit_QueueLink_head(QLink &QL, LinkNode* head)
{
	//LinkNode* p = QL->head->next;//p指向队头结点的下一个结点(跳过队头结点,因为队头结点没有存放东西)


	//BitNode* node = p->node;
	//printf("\n删除队列元素 %d 成功!", QL->head->node->data);

	//QL->head = QL->head->next;//头指针移位

	//printf("\n队头元素:%d", QL->head->node->data);

	//printf("\n输出:");
	printf(" %d ",head->node->data);
	//printf("\n!");
	

}


//初始化二叉树的树根
void Init_BiTree(BiTree &T,int e)
{
	T->data = e;
	T->lchild = NULL;
	T->rchild = NULL;

}


//为结点N添加左孩子
void insert_lchild(BitNode* &N)
{
	BitNode* child = (BitNode*)malloc(sizeof(BitNode));
	int flag = 1;
	int e;

	printf("\n%d->lchild==NULL请按1,%d->lchild==int(有意义)请按2:",N->data,N->data);
	scanf_s("%d",&flag);

	if (flag==2)
	{
		printf("\n请输入%d->lchild的值(int):",N->data);
		scanf_s("%d",&e);
		child->data = e;
		child->lchild = NULL;
		child->rchild = NULL;
	}
	else
	{
		child = NULL;
	}

	N->lchild = child;
}

//为结点N添加右孩子
void insert_rchild(BitNode*& N)
{
	BitNode* child = (BitNode*)malloc(sizeof(BitNode));
	int flag = 1;
	int e;

	printf("\n%d->rchild==NULL请按1,%d->rchild==int(有意义)请按2:", N->data, N->data);
	scanf_s("%d", &flag);

	if (flag == 2)
	{
		printf("\n请输入%d->rchild的值(int):", N->data);
		scanf_s("%d", &e);
		child->data = e;
		child->lchild = NULL;
		child->rchild = NULL;
	}
	else
	{
		child = NULL;
	}

	N->rchild = child;
}




//为二叉树树根T创建二叉树的枝叶(递归)
void creat_Tree(BiTree &T)
{
	if (T!=NULL)
	{
		insert_lchild(T);//为T结点增加左孩子
		creat_Tree(T->lchild);//为T->lchild结点创建枝叶

		insert_rchild(T);//为T结点增加右孩子
		creat_Tree(T->rchild);//为T->rchild结点创建枝叶
	}
}


//输出嘛
void visitBT(BitNode* node)
{
	printf(" %d ", node->data);
}


//先序遍历二叉树(根左右)

void PreBT_ER(BiTree T)
{
	if (T != NULL)
	{
		visitBT(T);//根
		PreBT_ER(T->lchild);//左
		PreBT_ER(T->rchild);//右
	}
}

//中序遍历二叉树(左根右)

void InBT_ER(BiTree T)
{
	if (T != NULL)
	{
		InBT_ER(T->lchild);
		visitBT(T);
		InBT_ER(T->rchild);
	}
}

//后序遍历二叉树(左右根)

void PostBT_ER(BiTree T)
{
	if (T != NULL)
	{
		PostBT_ER(T->lchild);
		PostBT_ER(T->rchild);
		visitBT(T);
	}

}

void Que_ER(QLink QL)
{
	LinkNode* p=QL->head;
	while (p != NULL)
	{
		printf(" %d ",p->node->data);
		p = p->next;
	}
}

/*层次遍历: 利用 队列 按照 层次遍历 的顺序  来存储二叉树的结点地址,以此来实现层次遍历二叉树*/

//用队列来实现层次遍历

void level_ER(BiTree T,QLink QL)
{
	
	printf("\n层次遍历:\n");
	//先把二叉树树根结点插入队列(刚开始的队头)
	insert_QueueLink_rear(QL, T);//第一个结点是在头结点之后,头结点不存放东西
	QL->head = QL->head->next;
	//每次只要队列里还有元素就:(1)把队头结点的左右孩子都插入到队尾(插入队列,队尾操作);(2)把队头输出(输出队列,队头操作)
	while (QL->head!=NULL)//由于 visit_QueueLink_head(&QL) 列表QL是引用的,所以QL会随之变化,所以QL->head也是相对应变化了的
	{
		visit_QueueLink_head(QL,QL->head);//访问并打印QL->head指向的队列结点的二叉树结点的值
		if(T->lchild!=NULL)//插入该节点的左右孩子(如果存在的话)
		{
			insert_QueueLink_rear(QL, T->lchild);
		}
		if(T->rchild!=NULL)
		{
			insert_QueueLink_rear(QL, T->rchild);
		}
		QL->head = QL->head->next;
		T=QL->head->node;
		
	}
	printf("\n队列创建完成!");


	printf("\n层次遍历结束!");

}


void testT()
{
	BiTree T = (BiTree)malloc(sizeof(BitNode));//二叉树
	QLink QL = (QLink)malloc(sizeof(QueueLink));//队列
	int e;
	Init_QLink(QL);
	printf("\n请输入二叉树的根节点的值:");
	scanf_s("%d", &e);
	Init_BiTree(T, e);
	printf("\n二叉树的根节点:%d 创建成功!", T->data);

	creat_Tree(T);

	printf("\n二叉树创建完成!");

	printf("\n先序遍历:\n");
	PreBT_ER(T);
	printf("\n中序遍历:\n");
	InBT_ER(T);
	printf("\n后序遍历:\n");
	PostBT_ER(T);
	printf("\n\n先序中序后序遍历完成!!\n");
	//层次遍历
	level_ER(T,QL);
}


int main()
{
	testT();
	return 0;
}

手算:

 

运行结果:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值