@@ -227,7 +227,8 @@ public:
227
227
## 其他语言版本
228
228
229
229
### Java:
230
- 迭代法前序遍历代码如下:
230
+
231
+ 迭代法前序遍历(空指针标记法)代码如下:
231
232
232
233
``` java
233
234
class Solution {
@@ -239,11 +240,10 @@ class Solution {
239
240
TreeNode node = st. peek();
240
241
if (node != null ) {
241
242
st. pop(); // 将该节点弹出,避免重复操作,下面再将右左中节点添加到栈中(前序遍历-中左右,入栈顺序右左中)
242
- if (node. right!= null ) st. push(node. right); // 添加右节点(空节点不入栈)
243
- if (node. left!= null ) st. push(node. left); // 添加左节点(空节点不入栈)
244
- st. push(node); // 添加中节点
243
+ if (node. right != null ) st. push(node. right); // 添加右节点(空节点不入栈)
244
+ if (node. left != null ) st. push(node. left); // 添加左节点(空节点不入栈)
245
+ st. push(node); // 添加中节点
245
246
st. push(null ); // 中节点访问过,但是还没有处理,加入空节点做为标记。
246
-
247
247
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
248
248
st. pop(); // 将空节点弹出
249
249
node = st. peek(); // 重新取出栈中元素
@@ -256,34 +256,34 @@ class Solution {
256
256
}
257
257
```
258
258
259
- 迭代法中序遍历代码如下:
259
+ 迭代法中序遍历(空指针标记法)代码如下:
260
260
``` java
261
261
class Solution {
262
- public List<Integer > inorderTraversal (TreeNode root ) {
262
+ public List<Integer > inorderTraversal (TreeNode root ) {
263
263
List<Integer > result = new LinkedList<> ();
264
- Stack<TreeNode > st = new Stack<> ();
265
- if (root != null ) st. push(root);
266
- while (! st. empty()) {
267
- TreeNode node = st. peek();
268
- if (node != null ) {
269
- st. pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中(中序遍历-左中右,入栈顺序右中左)
270
- if (node. right!= null ) st. push(node. right); // 添加右节点(空节点不入栈)
271
- st. push(node); // 添加中节点
272
- st. push(null ); // 中节点访问过,但是还没有处理,加入空节点做为标记。
273
- if (node. left!= null ) st. push(node. left); // 添加左节点(空节点不入栈)
274
- } else { // 只有遇到空节点的时候,才将下一个节点放进结果集
275
- st. pop(); // 将空节点弹出
276
- node = st. peek(); // 重新取出栈中元素
277
- st. pop();
278
- result. add(node. val); // 加入到结果集
264
+ Stack<TreeNode > st = new Stack<> ();
265
+ if (root != null ) st. push(root);
266
+ while (! st. empty()) {
267
+ TreeNode node = st. peek();
268
+ if (node != null ) {
269
+ st. pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中(中序遍历-左中右,入栈顺序右中左)
270
+ if (node. right != null ) st. push(node. right); // 添加右节点(空节点不入栈)
271
+ st. push(node); // 添加中节点
272
+ st. push(null ); // 中节点访问过,但是还没有处理,加入空节点做为标记。
273
+ if (node. left != null ) st. push(node. left); // 添加左节点(空节点不入栈)
274
+ } else { // 只有遇到空节点的时候,才将下一个节点放进结果集
275
+ st. pop(); // 将空节点弹出
276
+ node = st. peek(); // 重新取出栈中元素
277
+ st. pop();
278
+ result. add(node. val); // 加入到结果集
279
+ }
279
280
}
281
+ return result;
280
282
}
281
- return result;
282
- }
283
283
}
284
284
```
285
285
286
- 迭代法后序遍历代码如下:
286
+ 迭代法后序遍历(空指针标记法)代码如下:
287
287
``` java
288
288
class Solution {
289
289
public List<Integer > postorderTraversal (TreeNode root ) {
@@ -294,11 +294,10 @@ class Solution {
294
294
TreeNode node = st. peek();
295
295
if (node != null ) {
296
296
st. pop(); // 将该节点弹出,避免重复操作,下面再将中右左节点添加到栈中(后序遍历-左右中,入栈顺序中右左)
297
- st. push(node); // 添加中节点
297
+ st. push(node); // 添加中节点
298
298
st. push(null ); // 中节点访问过,但是还没有处理,加入空节点做为标记。
299
299
if (node. right!= null ) st. push(node. right); // 添加右节点(空节点不入栈)
300
- if (node. left!= null ) st. push(node. left); // 添加左节点(空节点不入栈)
301
-
300
+ if (node. left!= null ) st. push(node. left); // 添加左节点(空节点不入栈)
302
301
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
303
302
st. pop(); // 将空节点弹出
304
303
node = st. peek(); // 重新取出栈中元素
@@ -311,6 +310,150 @@ class Solution {
311
310
}
312
311
```
313
312
313
+ 迭代法前序遍历(boolean 标记法)代码如下:
314
+
315
+ ``` java
316
+ // LeetCode提交时注意添加导包语句
317
+ import java.util.AbstractMap.SimpleEntry ;
318
+
319
+ class Solution {
320
+ public List<Integer > preorderTraversal (TreeNode root ) {
321
+ List<Integer > result = new ArrayList<> ();
322
+ if (root == null )
323
+ return result;
324
+ Stack<SimpleEntry<TreeNode , Boolean > > stack = new Stack<> ();
325
+ stack. push(new SimpleEntry<> (root, false ));
326
+
327
+ while (! stack. isEmpty()) {
328
+ TreeNode node = stack. peek(). getKey();
329
+ // 多加一个visited参数,使“迭代统一写法”成为一件简单的事
330
+ boolean visited = stack. peek(). getValue();
331
+ stack. pop();
332
+
333
+ // visited为True,表示该节点和两个儿子位次之前已经安排过了,现在可以收割节点了
334
+ if (visited) {
335
+ result. add(node. val);
336
+ continue ;
337
+ }
338
+
339
+ // visited当前为false, 表示初次访问本节点,此次访问的目的是“把自己和两个儿子在栈中安排好位次”
340
+
341
+ // 前序遍历是'中左右',右儿子最先入栈,最后出栈
342
+ if (node. right != null ) {
343
+ stack. push(new SimpleEntry<> (node. right, false ));
344
+ }
345
+
346
+ // 左儿子位置居中
347
+ if (node. left != null ) {
348
+ stack. push(new SimpleEntry<> (node. left, false ));
349
+ }
350
+
351
+ // 节点自己最后入栈,最先出栈
352
+ // 同时,设置 visited 为 true,表示下次再访问本节点时,允许收割
353
+ stack. push(new SimpleEntry<> (node, true ));
354
+ }
355
+
356
+ return result;
357
+ }
358
+ }
359
+ ```
360
+
361
+ 迭代法中序遍历(boolean 标记法)代码如下:
362
+
363
+ ``` java
364
+ // LeetCode提交时注意添加导包语句
365
+ import java.util.AbstractMap.SimpleEntry ;
366
+
367
+ class Solution {
368
+ public List<Integer > inorderTraversal (TreeNode root ) {
369
+ List<Integer > result = new ArrayList<> ();
370
+ if (root == null )
371
+ return result;
372
+ Stack<SimpleEntry<TreeNode , Boolean > > stack = new Stack<> ();
373
+ stack. push(new SimpleEntry<> (root, false ));
374
+
375
+ while (! stack. isEmpty()) {
376
+ TreeNode node = stack. peek(). getKey();
377
+ // 多加一个visited参数,使“迭代统一写法”成为一件简单的事
378
+ boolean visited = stack. peek(). getValue();
379
+ stack. pop();
380
+
381
+ // visited为True,表示该节点和两个儿子位次之前已经安排过了,现在可以收割节点了
382
+ if (visited) {
383
+ result. add(node. val);
384
+ continue ;
385
+ }
386
+
387
+ // visited当前为false, 表示初次访问本节点,此次访问的目的是“把自己和两个儿子在栈中安排好位次”
388
+
389
+ // 中序遍历是'左中右',右儿子最先入栈,最后出栈
390
+ if (node. right != null ) {
391
+ stack. push(new SimpleEntry<> (node. right, false ));
392
+ }
393
+
394
+ // 把自己加回到栈中,位置居中
395
+ // 同时,设置 visited 为 true,表示下次再访问本节点时,允许收割
396
+ stack. push(new SimpleEntry<> (node, true ));
397
+
398
+ // 左儿子最后入栈,最先出栈
399
+ if (node. left != null ) {
400
+ stack. push(new SimpleEntry<> (node. left, false ));
401
+ }
402
+ }
403
+
404
+ return result;
405
+ }
406
+ }
407
+ ```
408
+
409
+ 迭代法后序遍历(boolean 标记法)代码如下:
410
+
411
+ ``` java
412
+ // LeetCode提交时注意添加导包语句
413
+ import java.util.AbstractMap.SimpleEntry ;
414
+
415
+ class Solution {
416
+ public List<Integer > postorderTraversal (TreeNode root ) {
417
+ List<Integer > result = new ArrayList<> ();
418
+ if (root == null )
419
+ return result;
420
+ Stack<SimpleEntry<TreeNode , Boolean > > stack = new Stack<> ();
421
+ stack. push(new SimpleEntry<> (root, false ));
422
+
423
+ while (! stack. isEmpty()) {
424
+ TreeNode node = stack. peek(). getKey();
425
+ // 多加一个visited参数,使“迭代统一写法”成为一件简单的事
426
+ boolean visited = stack. peek(). getValue();
427
+ stack. pop();
428
+
429
+ // visited为True,表示该节点和两个儿子位次之前已经安排过了,现在可以收割节点了
430
+ if (visited) {
431
+ result. add(node. val);
432
+ continue ;
433
+ }
434
+
435
+ // visited当前为false, 表示初次访问本节点,此次访问的目的是“把自己和两个儿子在栈中安排好位次”
436
+
437
+ // 后序遍历是'左右中',节点自己最先入栈,最后出栈
438
+ // 同时,设置 visited 为 true,表示下次再访问本节点时,允许收割
439
+ stack. push(new SimpleEntry<> (node, true ));
440
+
441
+ // 右儿子位置居中
442
+ if (node. right != null ) {
443
+ stack. push(new SimpleEntry<> (node. right, false ));
444
+ }
445
+
446
+ // 左儿子最后入栈,最先出栈
447
+ if (node. left != null ) {
448
+ stack. push(new SimpleEntry<> (node. left, false ));
449
+ }
450
+ }
451
+
452
+ return result;
453
+ }
454
+ }
455
+ ```
456
+
314
457
### Python:
315
458
316
459
> 迭代法前序遍历(空指针标记法):
0 commit comments