二叉树的层序遍历(C语言)

如图所示的二叉树:
现在编写算法,要求一层一层的输出二叉树结点值,例如:
A
B C
D E F
G H
思想:
使用队列实现二叉树广度优先遍历
1、首先将二叉树的根节点push到队列中,判断队列不为NULL,就输出队头的元素,
2、判断节点如果有孩子,就将孩子push到队列中,
3、遍历过的节点出队列,
4、循环以上操作,直到Tree == NULL。
编写队列的注意事项:
1.链式队列,要求有链表,这里链表的结点元素是二叉树的结点
2.队列要改造以下,要有队列元素的值。
3.队列入队时,size++,出队时size--
具体思想:
1.如果节点不为空,入队:

2.出队,读取队头节点元素:A

3.判断出队的节点是否有孩子,有孩子,直接入队:

4.出队,读取队头元素:B

5.判断B有没有孩子,有孩子,直接入队:

6.重复以上步骤:
总结:
入队,出队,判断出队元素节点有没有孩子,有的话直接入队
//用到了,队列,链表,二叉树
typedef struct BiNode{
char data;
struct BiNode *lchild,*rchild;
}BiNode,*Bitree;
typedef struct LinkNode{
Bitree data;
struct LinkNode *next;
}LinkNode,*LinkPtr; //链表里面存储的是二叉树的结点
typedef struct QueueNode{
LinkPtr front;
LinkPtr rear;
int size;
}QueueNode,*Queue; //链式队列需要一个链表,链表结点装入二叉树的结点
void Init_Queue(Queue &Q){ //初始化队列
Q=(Queue)malloc(sizeof(QueueNode));
LinkPtr Head=(LinkPtr)malloc(sizeof(LinkNode));
Head->next=NULL;
Q->size=0;
Q->front=Head;
Q->rear=Head;
}
void In_Queue(Queue Q,Bitree T){ //入队
LinkPtr p=(LinkPtr)malloc(sizeof(LinkNode));
p->data=T;
p->next=NULL;
Q->rear->next=p;
Q->rear=p;
Q->size++;
}
Bitree De_Queue(Queue Q){ //出队
LinkPtr p=Q->front->next;
Bitree e=p->data;
Q->front->next=p->next;
if(p==Q->rear)
Q->rear=Q->front;
Q->size--;
return e;
}
void CreateBitree(Bitree &T){//二叉树的建立
char ch;
scanf("%c",&ch);
if(ch=='#'||ch=='\n')T=NULL;
else {
T=(Bitree)malloc(sizeof(BiNode));
T->data=ch;
CreateBitree(T->lchild);
CreateBitree(T->rchild);
}
}
void FloorOrderTraverse(Bitree T){
Queue Q;
Init_Queue(Q);
if(T){
In_Queue(Q,T); //入队
}
while(Q->rear!=Q->front){
int size=Q->size;//保证每一行的元素个数
//每一次入队时,队列的元素个数会增加
col=0;
for(int i=0;i<size;i++){
Bitree e=De_Queue(Q); //出队
//保存即将出队的二叉树结点。
result[row][col++]=e->data;//开始存入二维数组
//printf("%c",e->data);
if(e->lchild)In_Queue(Q,e->lchild);//判断出队元素是否有孩子,有孩子就入队
if(e->rchild)In_Queue(Q,e->rchild);
}
//printf("\n");
row++;//该层二叉树的结点遍历完毕,转下一层
}
}
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#define Status int
#define OK 1
#define ERROR -1
char result[100][100]={'\0'};//二维数组储存每一行的二叉树结点值
int row=0,col=0;
typedef struct BiNode{
char data;
struct BiNode *lchild,*rchild;
}BiNode,*Bitree;
typedef struct LinkNode{
Bitree data;
struct LinkNode *next;
}LinkNode,*LinkPtr; //链表里面存储的是二叉树的结点
typedef struct QueueNode{
LinkPtr front;
LinkPtr rear;
int size;
}QueueNode,*Queue; //链式队列需要一个链表,链表结点装入二叉树的结点
void Init_Queue(Queue &Q){ //初始化队列
Q=(Queue)malloc(sizeof(QueueNode));
LinkPtr Head=(LinkPtr)malloc(sizeof(LinkNode));
Head->next=NULL;
Q->size=0;
Q->front=Head;
Q->rear=Head;
}
void In_Queue(Queue Q,Bitree T){ //入队
LinkPtr p=(LinkPtr)malloc(sizeof(LinkNode));
p->data=T;
p->next=NULL;
Q->rear->next=p;
Q->rear=p;
Q->size++;
}
Bitree De_Queue(Queue Q){ //出队
LinkPtr p=Q->front->next;
Bitree e=p->data;
Q->front->next=p->next;
if(p==Q->rear)
Q->rear=Q->front;
Q->size--;
return e;
}
void CreateBitree(Bitree &T){//二叉树的建立
char ch;
scanf("%c",&ch);
if(ch=='#'||ch=='\n')T=NULL;
else {
T=(Bitree)malloc(sizeof(BiNode));
T->data=ch;
CreateBitree(T->lchild);
CreateBitree(T->rchild);
}
}
void FloorOrderTraverse(Bitree T){
Queue Q;
Init_Queue(Q);
if(T){
In_Queue(Q,T); //入队
}
while(Q->rear!=Q->front){
int size=Q->size;//保证每一行的元素个数
//每一次入队时,队列的元素个数会增加
col=0;
for(int i=0;i<size;i++){
Bitree e=De_Queue(Q); //出队
//保存即将出队的二叉树结点。
result[row][col++]=e->data;//开始存入二维数组
//printf("%c",e->data);
if(e->lchild)In_Queue(Q,e->lchild);//判断出队元素是否有孩子,有孩子就入队
if(e->rchild)In_Queue(Q,e->rchild);
}
//printf("\n");
row++;//该层二叉树的结点遍历完毕,转下一层
}
}
void Output_Result(char (*result)[100]){
for(int i=0;i<row;i++){
int n=strlen(result[i]);
for(int j=0;j<n;j++){
printf("%c ",result[i][j]);
}
printf("\n");
}
}
int main(){
Bitree T;
CreateBitree(T);
FloorOrderTraverse(T);
Output_Result(result);
return 0;
}
#define Maxsize 2e3
typedef struct Queue{
struct TreeNode **base;
int front;
int rear;
int size;
}QNode,*QueuePtr;
void Init_Queue(QueuePtr Q){
Q->base=(struct TreeNode**)malloc(sizeof(struct TreeNode*)*Maxsize);
Q->front=Q->rear=0;
Q->size=0;
}
void Push(QueuePtr Q,struct TreeNode* e){
Q->base[Q->rear++]=e;
Q->size++;
}
struct TreeNode* Pop(QueuePtr Q){
struct TreeNode *e=Q->base[Q->front++];
Q->size--;
return e;
}
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
*returnSize=0;
if(!root){
return NULL;
}
QNode Q;
Init_Queue(&Q);
Push(&Q,root);
int **ans=(int**)malloc(sizeof(int*)*Maxsize);
*returnColumnSizes=(int*)malloc(sizeof(int)*Maxsize);
while(Q.front!=Q.rear){
int n=Q.size;
(*returnColumnSizes)[*returnSize]=n;
ans[*returnSize]=(int*)malloc(sizeof(int)*n);
for(int i=0;i<n;i++){
struct TreeNode *p=Pop(&Q);
ans[*returnSize][i]=p->val;
if(p->left)Push(&Q,p->left);
if(p->right)Push(&Q,p->right);
}
*returnSize=*returnSize+1;
}
return ans;
}
输入与输出:


本程序成功的将二叉树按层序遍历成功,并且可以把每一层的节点元素输出,可以作为标准模板。
本程序实现用到的网站:
https://blog.csdn.net/m0_37925202/article/details/80796010
https://programmercarl.com/0102.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%B1%82%E5%BA%8F%E9%81%8D%E5%8E%86.html
题目:
https://leetcode.cn/problems/binary-tree-level-order-traversal/
2022年11月19日夜

浙公网安备 33010602011771号