1
1
## 题目地址
2
2
https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
3
3
4
+ > 我要打十个!
5
+
6
+ 看完这篇文章虽然不能打十个,但是可以迅速打五个!而且够快!
7
+
8
+
9
+ # 102.二叉树的层序遍历
10
+
11
+ 给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
12
+
13
+ <img src =' ../pics/102.二叉树的层序遍历.png ' width =600 > </img ></div >
14
+
4
15
## 思路
5
16
6
- 我们之前讲过了,二叉树的深度优先遍历:[ 一文学通二叉树前中后序递归法与迭代法] ( https://github.com/youngyangyang04/leetcode/blob/master/problems/0144.二叉树的前序遍历.md ) 里面有前中后序遍历的方式,前中后序分辨可以使用递归和迭代的方法来实现,接下来我们再来介绍二叉树的另一种遍历方式,也就是层序遍历。
17
+ 我们之前讲过了三篇关于二叉树的深度优先遍历的文章:
18
+
19
+ * [ 二叉树:前中后序递归法] ( https://mp.weixin.qq.com/s/PwVIfxDlT3kRgMASWAMGhA )
20
+ * [ 二叉树:前中后序迭代法] ( https://mp.weixin.qq.com/s/c_zCrGHIVlBjUH_hJtghCg )
21
+ * [ 二叉树:前中后序迭代方式统一写法] ( https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRg )
7
22
8
- 相似题目:
9
- * [ 0102.二叉树的层序遍历] ( https://github.com/youngyangyang04/leetcode/blob/master/problems/0102.二叉树的层序遍历.md )
10
- * [ 0107.二叉树的层次遍历II] ( https://github.com/youngyangyang04/leetcode/blob/master/problems/0107.二叉树的层次遍历II.md )
11
- * [ 0199.二叉树的右视图] ( https://github.com/youngyangyang04/leetcode/blob/master/problems/0199.二叉树的右视图.md )
12
- * [ 0637.二叉树的层平均值] ( https://github.com/youngyangyang04/leetcode/blob/master/problems/0637.二叉树的层平均值.md )
23
+ 接下来我们再来介绍二叉树的另一种遍历方式:层序遍历。
13
24
14
25
层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。
15
26
16
- 需要借用一个辅助数据结构队列来实现 ,** 队列先进先出,符合一层一层遍历的逻辑,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。**
27
+ 需要借用一个辅助数据结构即队列来实现 ,** 队列先进先出,符合一层一层遍历的逻辑,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。**
17
28
18
- 使用队列实现广度优先遍历,动画如下:
29
+ ** 而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。 **
19
30
31
+ 使用队列实现二叉树广度优先遍历,动画如下:
32
+
33
+ ![ 102二叉树的层序遍历.mp4] ( ad3d58a5-b8ee-42a5-bc89-6ad4d9e3cbf2 )
20
34
<video src =' ../video/102二叉树的层序遍历.mp4 ' controls =' controls ' width =' 640 ' height =' 320 ' autoplay =' autoplay ' > Your browser does not support the video tag.</video ></div >
21
35
22
36
这样就实现了层序从左到右遍历二叉树。
23
37
24
- 代码如下:这份代码也可以作为二叉树层序遍历的模板。
38
+ 代码如下:** 这份代码也可以作为二叉树层序遍历的模板,以后在打四个就靠它了 ** 。
25
39
26
40
## C++代码
27
41
@@ -35,7 +49,8 @@ public:
35
49
while (!que.empty()) {
36
50
int size = que.size();
37
51
vector<int> vec;
38
- for (int i = 0; i < size; i++) {// 这里一定要使用固定大小size,不要使用que.size()
52
+ // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
53
+ for (int i = 0; i < size; i++) {
39
54
TreeNode* node = que.front();
40
55
que.pop();
41
56
vec.push_back(node->val);
@@ -49,4 +64,186 @@ public:
49
64
};
50
65
```
51
66
67
+ ** 此时我们就掌握了二叉树的层序遍历了,那么如下四道leetcode上的题目,只需要修改模板的一两行代码(不能再多了),便可打倒!**
68
+
69
+ # 107.二叉树的层次遍历 II
70
+
71
+ 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
72
+
73
+ <img src =' ../pics/107.二叉树的层次遍历II.png ' width =600 > </img ></div >
74
+
75
+ ## 思路
76
+
77
+ 相对于102.二叉树的层序遍历,就是最后把result数组反转一下就可以了。
78
+
79
+ ## C++代码
80
+
81
+ ```
82
+ class Solution {
83
+ public:
84
+ vector<vector<int>> levelOrderBottom(TreeNode* root) {
85
+ queue<TreeNode*> que;
86
+ if (root != NULL) que.push(root);
87
+ vector<vector<int>> result;
88
+ while (!que.empty()) {
89
+ int size = que.size();
90
+ vector<int> vec;
91
+ for (int i = 0; i < size; i++) {
92
+ TreeNode* node = que.front();
93
+ que.pop();
94
+ vec.push_back(node->val);
95
+ if (node->left) que.push(node->left);
96
+ if (node->right) que.push(node->right);
97
+ }
98
+ result.push_back(vec);
99
+ }
100
+ reverse(result.begin(), result.end()); // 在这里反转一下数组即可
101
+ return result;
102
+
103
+ }
104
+ };
105
+ ```
106
+
107
+
108
+ # 199.二叉树的右视图
109
+
110
+ 给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
111
+
112
+ <img src =' ../pics/199.二叉树的右视图.png ' width =600 > </img ></div >
113
+
114
+ ## 思路
115
+
116
+ 层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。
117
+
118
+ ## C++代码
119
+
120
+ ```
121
+ class Solution {
122
+ public:
123
+ vector<int> rightSideView(TreeNode* root) {
124
+ queue<TreeNode*> que;
125
+ if (root != NULL) que.push(root);
126
+ vector<int> result;
127
+ while (!que.empty()) {
128
+ int size = que.size();
129
+ for (int i = 0; i < size; i++) {
130
+ TreeNode* node = que.front();
131
+ que.pop();
132
+ if (i == (size - 1)) result.push_back(node->val); // 将每一层的最后元素放入result数组中
133
+ if (node->left) que.push(node->left);
134
+ if (node->right) que.push(node->right);
135
+ }
136
+ }
137
+ return result;
138
+ }
139
+ };
140
+ ```
141
+
142
+ # 637.二叉树的层平均值
143
+
144
+ 给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。
145
+
146
+ <img src =' ../pics/637.二叉树的层平均值.png ' width =600 > </img ></div >
147
+
148
+ ## 思路
149
+
150
+ 本题就是层序遍历的时候把一层求个总和在取一个均值。
151
+
152
+ ## C++代码
153
+
154
+ ```
155
+ class Solution {
156
+ public:
157
+ vector<double> averageOfLevels(TreeNode* root) {
158
+ queue<TreeNode*> que;
159
+ if (root != NULL) que.push(root);
160
+ vector<double> result;
161
+ while (!que.empty()) {
162
+ int size = que.size();
163
+ double sum = 0; // 统计每一层的和
164
+ for (int i = 0; i < size; i++) {
165
+ TreeNode* node = que.front();
166
+ que.pop();
167
+ sum += node->val;
168
+ if (node->left) que.push(node->left);
169
+ if (node->right) que.push(node->right);
170
+ }
171
+ result.push_back(sum / size); // 将每一层均值放进结果集
172
+ }
173
+ return result;
174
+ }
175
+ };
176
+
177
+ ```
178
+
179
+ # 429.N叉树的层序遍历
180
+
181
+ 给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。
182
+
183
+ 例如,给定一个 3叉树 :
184
+
185
+
186
+ <img src =' ../pics/429. N叉树的层序遍历.png ' width =600 > </img ></div >
187
+
188
+ 返回其层序遍历:
189
+
190
+ [
191
+ [ 1] ,
192
+ [ 3,2,4] ,
193
+ [ 5,6]
194
+ ]
195
+
196
+
197
+ ## 思路
198
+
199
+ 这道题依旧是模板题,只不过一个节点有多个孩子了
200
+
201
+ ## C++代码
202
+
203
+ ```
204
+ class Solution {
205
+ public:
206
+ vector<vector<int>> levelOrder(Node* root) {
207
+ queue<Node*> que;
208
+ if (root != NULL) que.push(root);
209
+ vector<vector<int>> result;
210
+ while (!que.empty()) {
211
+ int size = que.size();
212
+ vector<int> vec;
213
+ for (int i = 0; i < size; i++) {
214
+ Node* node = que.front();
215
+ que.pop();
216
+ vec.push_back(node->val);
217
+ for (int i = 0; i < node->children.size(); i++) { // 将节点孩子加入队列
218
+ if (node->children[i]) que.push(node->children[i]);
219
+ }
220
+ }
221
+ result.push_back(vec);
222
+ }
223
+ return result;
224
+
225
+ }
226
+ };
227
+ ```
228
+
229
+ # 总结
230
+
231
+ 二叉树的层序遍历,就是图论中的广度优先搜索在二叉树中的应用,需要借助队列来实现(此时是不是又发现队列的应用了)。
232
+
233
+ 学会二叉树的层序遍历,可以一口气撸完leetcode上五道题目:
234
+
235
+ * 102.二叉树的层序遍历
236
+ * 107.二叉树的层次遍历II
237
+ * 199.二叉树的右视图
238
+ * 637.二叉树的层平均值
239
+ * 589.N叉树的前序遍历
240
+
241
+ 虽然不能一口气打十个,打五个也还行。
242
+
243
+ 如果非要打十个,还得找叶师傅!
244
+
245
+ <img src =' ../pics/我要打十个.gif ' width =600 > </img ></div >
246
+
247
+
248
+
52
249
> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
0 commit comments