给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1] 输出:[[1]]
示例 3:
输入:root = [] 输出:[]
代码:
// returnSize:指向一个整数,用于返回结果二维数组的行数(即二叉树的层次数)
// returnColumnSizes:指向一个指针,该指针指向的数组用于存储二维数组每一行的列数(即每层节点个数)
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
// 初始化返回结果的行数为0
*returnSize = 0;
// 如果根节点为空,直接返回NULL,表示空树没有层次遍历结果
if (root == NULL)
return NULL;
// 动态分配内存用于存储层次遍历结果的二维数组指针数组
// 假设二叉树最多有2001层,这里分配足够的空间来存储每层节点值数组的指针
int** returnNums = (int**)malloc(sizeof(int*) * 2001);
// 为存储每层节点个数的数组动态分配内存,同样假设最多有2001层
*returnColumnSizes = (int*)malloc(sizeof(int) * 2001);
// 定义一个数组作为队列,用于辅助层次遍历,存储二叉树节点指针
struct TreeNode* queueDat[2001];
// 队列的队首索引,初始化为0,用于指示从队列取节点的位置
int queueFront = 0;
// 队列的队尾索引,初始化为0,用于指示向队列插入节点的位置
int queueRear = 0;
// 定义一个指针变量,用于临时存储当前正在处理的节点
struct TreeNode* cur;
// 将根节点放入队列中,然后队尾索引后移一位
queueDat[queueRear++] = root;
// 只要队列不为空,就进行循环处理每层节点
while (queueFront!= queueRear) {
// 用于记录当前层节点的个数,初始化为0
int colSize = 0;
// 记录当前层节点处理开始时队列的队尾位置(因为处理过程中队尾可能改变)
int last = queueRear;
// 为返回结果二维数组的当前行分配内存空间,大小根据当前层节点数量确定
returnNums[*returnSize] = (int*)malloc(sizeof(int) * (last - queueFront));
// 处理当前层的节点
while (queueFront < last) {
// 从队列中取出一个节点,赋值给cur,并将队首索引后移一位
cur = queueDat[queueFront++];
// 将当前节点的值存入返回结果二维数组的当前行、当前列位置
// 每存入一个节点值,colSize就自增1
returnNums[*returnSize][colSize++] = cur->val;
// 如果当前节点有左子节点,将左子节点放入队列中,队尾索引后移
if (cur->left!= NULL)
queueDat[queueRear++] = cur->left;
// 如果当前节点有右子节点,将右子节点放入队列中,队尾索引后移
if (cur->right!= NULL)
queueDat[queueRear++] = cur->right;
}
// 将当前层节点的个数存入存储每层节点个数的数组的当前行
(*returnColumnSizes)[*returnSize] = colSize;
// 表示已经处理完一层节点,返回结果二维数组的行数增加1
(*returnSize)++;
}
// 返回层次遍历结果的二维数组,其中每一行存储二叉树一层的节点值
return returnNums;
}