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


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

输入与输出:
1.png
2.png
本程序成功的将二叉树按层序遍历成功,并且可以把每一层的节点元素输出,可以作为标准模板。
本程序实现用到的网站:
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日夜

posted @ 2024-04-16 12:39  夏muer  阅读(361)  评论(0)    收藏  举报