题目
(1)从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
(2)示例如下:
给定二叉树: [3,9,20,null,null,15,7],
返回其层次遍历结果:
解决思路
- 思路1:采用递归思想解决
- 将树的节点存储在二维数组中,树中的每一行对应二维数组中的一个数组。并用 k 记录树的每一行应该存储在二维数组的第几个数组中。
- 具体步骤:
- 第一步:将根节点放入二维数组中下标为 k = 0 的数组中。
- 第二步:递归遍历根节点的左节点,并将节点的值放入二维数组中下标为 k + 1 的数组中。
- 第三步:递归遍历根节点的右节点,并将节点的值放入二维数组中下标为 k + 1 的数组中。
- 思路2:基于队列实现
- 具体步骤:
- 第一步:将根节点入队列。
- 第二步:根节点出队列,并将根节点的左右节点入队列。
- 第三步:根节点的左节点出队列,并将根节点的左节点的左右节点入队列。
- 第四步:根节点的右节点出队列,并将根节点的右节点的左右节点入队列。
代码
- 思路1对应的C++代码:
# include <stdio.h>
# include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(): val(0), left(nullptr), right(nullptr) {}
TreeNode(int _val): val(_val), left(nullptr), right(nullptr) {}
TreeNode(int _val, TreeNode* _left, TreeNode* _right): val(_val), left(_left), right(_right) {}
};
class Solution {
public:
void mylevelOrder(TreeNode* root, int k, vector<vector<int>>& answer) {
if (nullptr == root) {
return;
}
// 如果传入的k值和answer的size相等,说明二维数组answer中不存在下标为k的数组,则添加一个空数组。
if (k == answer.size()) {
answer.push_back(vector<int> ());
}
answer[k].push_back(root->val); // 第一步:将根节点放入二维数组中下标为 k = 0 的数组中。
mylevelOrder(root->left, k + 1, answer); // 第二步:递归遍历根节点的左节点,并将节点的值放入二维数组中下标为 k + 1 的数组中。
mylevelOrder(root->right, k + 1, answer); // 第三步:递归遍历根节点的右节点,并将节点的值放入二维数组中下标为 k + 1 的数组中。
}
vector<vector<int>> leverOrder(TreeNode* root) {
if (nullptr == root) {
return vector<vector<int>> ();
}
vector<vector<int>> answer; // 使用二维数组存储树中的每一层节点
int k = 0; // 记录树的每一层和二维数组的对应关系(当前根节点的值应该放到二维数组的第几号数组中)
mylevelOrder(root, k, answer);
return answer;
}
};
int main() {
TreeNode* n1 = new TreeNode(3);
TreeNode* n2 = new TreeNode(9);
TreeNode* n3 = new TreeNode(20);
TreeNode* n4 = new TreeNode(15);
TreeNode* n5 = new TreeNode(7);
n1->left = n2;
n1->right = n3;
n2->left = nullptr;
n2->right = nullptr;
n3->left = n4;
n3->right = n5;
n4->left = nullptr;
n4->right = nullptr;
n5->left = nullptr;
n5->right = nullptr;
Solution* solution = new Solution();
vector<vector<int>> result = solution->leverOrder(n1);
for (auto ret: result) {
for (auto r: ret) {
printf("%d ", r);
}
}
printf("\n");
return 0;
}
- 思路2对应的C++代码:
# include <stdio.h>
# include <vector>
# include <queue>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(): val(0), left(nullptr), right(nullptr) {}
TreeNode(int _val): val(_val), left(nullptr), right(nullptr) {}
TreeNode(int _val, TreeNode* _left, TreeNode* _right): val(_val), left(_left), right(_right) {}
};
class Solution {
public:
vector<vector<int>> leverOrder(TreeNode* root) {
if (nullptr == root) {
return vector<vector<int>> ();
}
vector<vector<int>> answer; // 使用二维数组存储树中的每一层节点
int k = 0; // 记录树的每一层和二维数组的对应关系(当前根节点的值应该放到二维数组的第几号数组中)
queue<TreeNode*> q; // 用于将树中的节点依次入队出队。
q.push(root); // 将根节点入队列
// 遍历队列中的每个点
while (!q.empty()) {
// 如果传入的k值和answer的size相等,说明二维数组answer中不存在下标为k的数组,则添加一个空数组。
if (k == answer.size()) {
answer.push_back(vector<int>());
}
// 将根节点出队列,并将左右节点入队列。
// 出队列时,每次将树中的一行节点出队列。
int q_size = q.size();
for (int i = 0; i < q_size; i++) {
// 将根节点的左节点入队列
if (q.front()->left) {
q.push(q.front()->left);
}
// 将根节点的右节点入队列
if (q.front()->right) {
q.push(q.front()->right);
}
answer[k].push_back(q.front()->val);
q.pop(); // 将根节点出队列
}
k++;
}
return answer;
}
};
int main() {
TreeNode* n1 = new TreeNode(3);
TreeNode* n2 = new TreeNode(9);
TreeNode* n3 = new TreeNode(20);
TreeNode* n4 = new TreeNode(15);
TreeNode* n5 = new TreeNode(7);
n1->left = n2;
n1->right = n3;
n2->left = nullptr;
n2->right = nullptr;
n3->left = n4;
n3->right = n5;
n4->left = nullptr;
n4->right = nullptr;
n5->left = nullptr;
n5->right = nullptr;
Solution* solution = new Solution();
vector<vector<int>> result = solution->leverOrder(n1);
for (auto ret: result) {
for (auto r: ret) {
printf("%d ", r);
}
}
printf("\n");
return 0;
}
- 思路1对应的Python代码:
# -*- coding: utf-8 -*-
from typing import List
class TreeNode:
def __init__(self, _val=0, _left=None, _right=None):
self.val = _val
self.left = _left;
self.right = _right
class Solution:
def __init__(self):
pass
def mylevelOrder(self, root: TreeNode, k: int, answer: List[List]):
if not root:
return
# 如果传入的k值和answer的size相等,说明二维数组answer中不存在下标为k的数组,则添加一个空数组。
if k == len(answer):
answer.append([])
answer[k].append(root.val) # 第一步:将根节点放入二维数组中下标为 k = 0 的数组中。
self.mylevelOrder(root.left, k + 1, answer) # 第二步:递归遍历根节点的左节点,并将节点的值放入二维数组中下标为 k + 1 的数组中。
self.mylevelOrder(root.right, k + 1, answer) # 第三步:递归遍历根节点的右节点,并将节点的值放入二维数组中下标为 k + 1 的数组中。
def levedOrder(self, root: TreeNode) -> List[List]:
if not root:
return []
answer: List[List] = [[]] # 使用二维数组存储树中的每一层节点
k: int = 0 # 记录树的每一层和二维数组的对应关系(当前根节点的值应该放到二维数组的第几号数组中)
self.mylevelOrder(root, k, answer)
return answer
def main():
n1 = TreeNode(3)
n2 = TreeNode(9)
n3 = TreeNode(20)
n4 = TreeNode(15)
n5 = TreeNode(7)
n1.left = n2
n1.right = n3
n2.left = None
n2.right = None
n3.left = n4
n3.right = n5
n4.left = None
n4.right = None
n5.left = None
n5.right = None
solution = Solution()
retsult = solution.levedOrder(n1)
for ret in retsult:
for r in ret:
print(r, end=' ')
if __name__ == "__main__":
main()
- 思路2对应的Python代码:
# -*- coding: utf-8 -*-
from typing import List
class TreeNode:
def __init__(self, _val=0, _left=None, _right=None):
self.val = _val
self.left = _left;
self.right = _right
class Solution:
def __init__(self):
pass
def levedOrder(self, root: TreeNode) -> List[List]:
if not root:
return []
answer: List[List] = [[]] # 使用二维数组存储树中的每一层节点
k: int = 0 # 记录树的每一层和二维数组的对应关系(当前根节点的值应该放到二维数组的第几号数组中)
q: List = [] # 用于将树中的节点依次入队出队。
q.append(root) # 将根节点入队列
# 遍历队列中的每个点
while q:
# 如果传入的k值和answer的size相等,说明二维数组answer中不存在下标为k的数组,则添加一个空数组。
if k == len(answer):
answer.append([])
# 将根节点出队列,并将左右节点入队列。
# 出队列时,每次将树中的一行节点出队列。
q_size = len(q)
for i in range(q_size):
# 将根节点的左节点入队列
if q[0].left:
q.append(q[0].left)
# 将根节点的右节点入队列
if q[0].right:
q.append(q[0].right)
answer[k].append(q[0].val)
q.pop(0) # 将根节点出队列
k += 1
return answer
def main():
n1 = TreeNode(3)
n2 = TreeNode(9)
n3 = TreeNode(20)
n4 = TreeNode(15)
n5 = TreeNode(7)
n1.left = n2
n1.right = n3
n2.left = None
n2.right = None
n3.left = n4
n3.right = n5
n4.left = None
n4.right = None
n5.left = None
n5.right = None
solution = Solution()
retsult = solution.levedOrder(n1)
for ret in retsult:
for r in ret:
print(r, end=' ')
if __name__ == "__main__":
main()
说明
- 对应LeetCode题目:“剑指 Offer 32 - II. 从上到下打印二叉树 II”。
- 链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/