问题描述:
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7]
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
通过
来源:力扣(LeetCode)
二叉树的层序遍历
目录
1.非递归用循环队列
2.递归实现层次遍历
在栈与队列:匹配问题都是栈的强项中提到,「递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中」,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。
知识前提:循环队列,二叉树的基本运算
非递归用循环队列
//思路
进行层次遍历时构建一个辅助队列,先将二叉树根节点入队,然后出队,访问出队结点,若它有左子树,将左子树根节点入队,然后出队,访问出队结点…,右子树也同样如此,循环往复直到队列为空
1.构建好辅助队列Q和二叉树T;
2.首先将二叉树的T(根节点)入队列;
3.进入while循环,退出条件 :队列为空;
4.循环内部:首先将队列中的队首元素出栈,并且输出他的值;
若队首元素(刚刚出队的元素)有左子树,将其左子树入队
若队首元素(刚刚出队的元素)有右子树,将其右子树入队
详细代码(可直接运行)
补充:如何让输出为一层一行
方法说起来很简单,只要仔细想,应该都能想出这种方法来。
定义两个变量curLevelCount和nextLevelCount来分别保存当前层和下一层的结点数。
显然,curLevelCount的初始值为1,因为只有一个根结点,而nextLevelCount由于未知,故置为0.
思路:
1.输出一行一行的与之前输出为一行的代码大体相似
2.构建好辅助队列Q和二叉树T;
3.再定义两个变量:curLevelCount用于记录当前层次结点个数,nextLevelCount用于记录当前层次的下一层结点的个数
4.将二叉树的根节点入栈,同时curLevelCount=1,nextLevelCount=0;
5.进入while循环,退出条件 :队列为空;
6.循环内部:首先将队列中的队首元素出栈,并且输出他的值;(与此同时,将curLevelCount–);
若队首元素(刚刚出队的元素)有左子树,将其左子树入队.(与此同时,将nextLevelCount++);
若队首元素(刚刚出队的元素)有右子树,将其右子树入队.(与此同时,将nextLevelCount++);
若curLevelCount减到零:输出一个换行符,将nextLevelCount赋值给curLevelCount,
nextLevelCount=0;
代码:非递归用循环队列
#include<stdio.h>
typedef int Status;
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 1
#include<malloc.h>
#include<stdlib.h>
#include<stdio.h>
#include<bits/stdc++.h>
typedef char TElemType;
typedef int status;
typedef struct BiNode
{
TElemType data;
struct BiNode *lchild;
struct BiNode *rchild;
}BiNode,*BiTree;
typedef BiTree ElemType;
typedef BiTree QElemType;
//----------循环队列 --顺序存储结构-----------------------
#define MAXQSIZE 100 // 最大队列长度+1
typedef struct {
ElemType *base; // 初始化的动态分配存储空间
int front; // 头指针,若队列不空,指向队列头元素
int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue;
void InitQueue(SqQueue &Q)
{
// 构造一个空队列Q
Q.base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
if(!Q.base) // 存储分配失败
exit(0);
Q.front = Q.rear = 0;
}
void DestroyQueue(SqQueue &Q)
{
// 销毁队列Q,Q不再存在
if(Q.base)
free(Q.base);
Q.base = NULL;
Q.front = Q.rear = 0;
}
int QueueLength(SqQueue &Q)
{
return ((Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);
}
Status EnQueue(SqQueue &Q, QElemType e)
{
// 插入元素e为Q的新的队尾元素
if((Q.rear + 1) % MAXQSIZE == Q.front) // 队列满
return ERROR;
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXQSIZE;
return OK;
}
Status DeQueue(SqQueue &Q, QElemType &e)
{
// 若队列不空,则删除Q的队头元素,用e返回其值,
// 并返回OK;否则返回ERROR
if(Q.front == Q.rear) // 队列空
return ERROR;
e = Q