力扣第102题: 二叉树的层序遍历
题目描述
给你一个二叉树,请你返回其按 层序遍历 的结果(即逐层从左到右访问所有节点)。
示例:
输入:
3
/ \
9 20
/ \
15 7
输出:
[
[3],
[9,20],
[15,7]
]
解题思路
层序遍历的关键在于使用一个队列:
- 初始时,将根节点入队。
- 每次处理队列中的一个层次:
- 获取当前队列长度
level_size
(表示当前层节点数)。 - 依次弹出队列中的
level_size
个节点,并将它们的值存入一个列表level
。 - 如果节点有左、右子节点,则将它们入队。
- 获取当前队列长度
- 将当前层的列表
level
添加到结果列表result
中。
实现代码(C语言)
结构体定义
为了实现层序遍历,使用一个队列结构。
#include <stdio.h>
#include <stdlib.h>
/**
* Definition for a binary tree node.
*/
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
// 队列节点
struct QueueNode {
struct TreeNode *node;
struct QueueNode *next;
};
// 队列操作
void enqueue(struct QueueNode **front, struct QueueNode **rear, struct TreeNode *node) {
struct QueueNode *newNode = (struct QueueNode *)malloc(sizeof(struct QueueNode));
newNode->node = node;
newNode->next = NULL;
if (*rear == NULL) {
*front = *rear = newNode;
} else {
(*rear)->next = newNode;
*rear = newNode;
}
}
struct TreeNode *dequeue(struct QueueNode **front, struct QueueNode **rear) {
if (*front == NULL) return NULL;
struct QueueNode *temp = *front;
struct TreeNode *node = temp->node;
*front = (*front)->next;
if (*front == NULL) *rear = NULL;
free(temp);
return node;
}
层序遍历实现
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
if (root == NULL) {
*returnSize = 0;
*returnColumnSizes = NULL;
return NULL;
}
// 初始化队列
struct QueueNode *front = NULL, *rear = NULL;
enqueue(&front, &rear, root);
// 动态分配初始空间
int capacity = 10; // 初始容量
int** result = (int**)malloc(capacity * sizeof(int*));
*returnColumnSizes = (int*)malloc(capacity * sizeof(int));
*returnSize = 0;
while (front != NULL) {
int level_size = 0;
struct QueueNode *temp = front;
// 统计当前层节点数量
while (temp != NULL) {
level_size++;
temp = temp->next;
}
// 如果超过当前容量,扩展空间
if (*returnSize >= capacity) {
capacity *= 2;
result = (int**)realloc(result, capacity * sizeof(int*));
*returnColumnSizes = (int*)realloc(*returnColumnSizes, capacity * sizeof(int));
if (result == NULL || *returnColumnSizes == NULL) {
fprintf(stderr, "内存分配失败\n");
exit(EXIT_FAILURE);
}
}
// 存储当前层的节点值
result[*returnSize] = (int*)malloc(level_size * sizeof(int));
if (result[*returnSize] == NULL) {
fprintf(stderr, "内存分配失败\n");
exit(EXIT_FAILURE);
}
(*returnColumnSizes)[*returnSize] = level_size;
for (int i = 0; i < level_size; i++) {
struct TreeNode *node = dequeue(&front, &rear);
result[*returnSize][i] = node->val;
if (node->left != NULL) enqueue(&front, &rear, node->left);
if (node->right != NULL) enqueue(&front, &rear, node->right);
}
(*returnSize)++;
}
return result;
}
测试代码
#include <stdio.h>
#include <stdlib.h>
// 创建二叉树节点
struct TreeNode* createNode(int val) {
struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
newNode->val = val;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// 打印二维数组
void printResult(int** result, int returnSize, int* returnColumnSizes) {
printf("[\n");
for (int i = 0; i < returnSize; i++) {
printf(" [");
for (int j = 0; j < returnColumnSizes[i]; j++) {
printf("%d", result[i][j]);
if (j < returnColumnSizes[i] - 1) printf(", ");
}
printf("]");
if (i < returnSize - 1) printf(",");
printf("\n");
}
printf("]\n");
}
// 主函数
int main() {
struct TreeNode* root = createNode(3);
root->left = createNode(9);
root->right = createNode(20);
root->right->left = createNode(15);
root->right->right = createNode(7);
int returnSize;
int* returnColumnSizes;
int** result = levelOrder(root, &returnSize, &returnColumnSizes);
printf("层序遍历结果:\n");
printResult(result, returnSize, returnColumnSizes);
// 释放内存
for (int i = 0; i < returnSize; i++) {
free(result[i]);
}
free(result);
free(returnColumnSizes);
return 0;
}
复杂度分析
-
时间复杂度:
- 每个节点访问一次,复杂度为 (O(n)),其中 (n) 是节点总数。
-
空间复杂度:
- 队列的大小取决于树的最大宽度,最坏情况是 (O(n))。
输出示例
输入:
3
/ \
9 20
/ \
15 7
输出:
层序遍历结果:
[
[3],
[9, 20],
[15, 7]
]