一【题目类别】
- 广度优先搜索
二【题目难度】
- 简单
三【题目编号】
- 剑指Offer 32-II.从上到下打印二叉树II
四【题目描述】
- 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
五【题目示例】
- 示例 1:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
六【题目提示】
- 节点总数 <= 1000
七【题目注意】
八【解题思路】
- 整体思路就是BFS,因为BFS要借助队列,先把头结点加入队列,然后把这个队列加入二维数组中,然后开始进行每一层的遍历,因为队列是先进先出,所以会一层一层的遍历下去,第一层的头结点结束后,开始第二层,依次向下把每一层的值都保存起来了
九【时间频度】
- 时间复杂度: O ( N ) O(N) O(N)
十【代码实现】
- Java语言版
package BFS;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class o32_II_PrintiBnaryTreeFromTopToBottomII {
int val;
o32_II_PrintiBnaryTreeFromTopToBottomII left;
o32_II_PrintiBnaryTreeFromTopToBottomII right;
o32_II_PrintiBnaryTreeFromTopToBottomII(int x) {
val = x;
}
public static void main(String[] args) {
// 创建这棵树
o32_II_PrintiBnaryTreeFromTopToBottomII root = new o32_II_PrintiBnaryTreeFromTopToBottomII(3);
o32_II_PrintiBnaryTreeFromTopToBottomII left = new o32_II_PrintiBnaryTreeFromTopToBottomII(9);
o32_II_PrintiBnaryTreeFromTopToBottomII right1 = new o32_II_PrintiBnaryTreeFromTopToBottomII(20);
o32_II_PrintiBnaryTreeFromTopToBottomII right2 = new o32_II_PrintiBnaryTreeFromTopToBottomII(15);
o32_II_PrintiBnaryTreeFromTopToBottomII right3 = new o32_II_PrintiBnaryTreeFromTopToBottomII(7);
root.left = left;
root.right = right1;
right1.left = right2;
right1.right = right3;
List<List<Integer>> res = levelOrder(root);
System.out.println("res = " + res);
}
public static List<List<Integer>> levelOrder(o32_II_PrintiBnaryTreeFromTopToBottomII root) {
// 存放节点的队列,利用先进先出的特性
Queue<o32_II_PrintiBnaryTreeFromTopToBottomII> queue = new LinkedList<>();
// 存放结果的二维数组
List<List<Integer>> result = new ArrayList();
// 将头结点加入队列
if (root != null) {
queue.add(root);
}
// 当队列不为空时开始遍历
while (!queue.isEmpty()) {
// 新建临时数组
List<Integer> temp = new ArrayList<>();
// 每层有几个节点就循环几次
for (int i = queue.size(); i > 0; i--) {
// 利用队列先进先出的特性,取出第一个节点,也就是这一层的第一个节点
o32_II_PrintiBnaryTreeFromTopToBottomII node = queue.poll();
// 将这个节点的值加入temp中
temp.add(node.val);
// 分别把左右节点加入temp中,也就是分别加入每一层的节点
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
// 把每一层的结果加入结果集中
result.add(temp);
}
// 返回结果
return result;
}
}
- C语言版
#define _CRT_SECURE_NO_WARNINGS
#include<stdint.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*定义树*/
struct TreeNode
{
int val;
struct TreeNode *left;
struct TreeNode *right;
};
void BFS(struct TreeNode **queueArr, int start, int end, int* returnSize, int** returnColumnSizes, int **retArr)
{
int i;
int flagStart = start;
int flagEnd = end;
int levelNum = end - start;
/*如果队列为空,则返回*/
if (levelNum == 0) {
return;
}
/*记录本层元素数量*/
(*returnColumnSizes)[*returnSize] = levelNum;
/*为本层返回数组申请内存*/
retArr[*returnSize] = (int *)malloc(sizeof(int) * levelNum);
/*填充该层返回数组内容*/
for (i = 0; i < levelNum; i++) {
retArr[*returnSize][i] = queueArr[start + i]->val;
}
/*层数++*/
(*returnSize)++;
/*将该层节点的子节点装入队列,注意判断子节点是否存在,该步也是广度优先遍历的重点*/
for (i = flagStart; i < flagEnd; i++) {
if (queueArr[start]->left != NULL) {
queueArr[end++] = queueArr[start]->left;
} if (queueArr[start]->right != NULL) {
queueArr[end++] = queueArr[start]->right;
}
start++;
}
/*继续遍历队列中的节点*/
BFS(queueArr, start, end, returnSize, returnColumnSizes, retArr);
return;
}
int** o32_II_PrintBinaryTreeFromTopToBottom_levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
*returnSize = 0;
if (root == NULL) {
return NULL;
}
/*为返回数组申请内存*/
int **retArr = (int **)malloc(sizeof(int *) * 10000);
memset(retArr, 0, sizeof(int *) * 10000);
/*为模拟队列的数组申请内存,要稍微大一点*/
struct TreeNode *queueArr[10000] = { { 0 } };
/*为储存返回组每一列大小的数组申请内存*/
*returnColumnSizes = (int *)malloc(sizeof(int) * 10000);
/*将根节点放入队列*/
queueArr[0] = root;
/*用start和end下标模拟进队出队*/
int start = 0;
int end = 1;
/*广度优先遍历*/
BFS(queueArr, start, end, returnSize, returnColumnSizes, retArr);
/*返回结果*/
return retArr;
}
/*主函数*/
int main(void)
{
/*主函数内容省略,上面的算法是核心*/
}
十一【提交结果】
-
Java语言版
-
C语言版