Skip to content

Commit ff8072f

Browse files
整理仓库;添加非递归遍历二叉树的通用模板
1 parent aa95b27 commit ff8072f

File tree

15 files changed

+56
-127
lines changed

15 files changed

+56
-127
lines changed
File renamed without changes.
File renamed without changes.
File renamed without changes.

data_structure/binary_tree.md renamed to 2.data_structure/1. binary_tree.md

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
### 二叉树遍历
66

7-
**前序遍历****先访问根节点**,再前序遍历左子树,再前序遍历右子树
8-
**中序遍历**:先中序遍历左子树,**再访问根节点**,再中序遍历右子树
9-
**后序遍历**:先后序遍历左子树,再后序遍历右子树,**再访问根节点**
7+
- **前序遍历****先访问根节点**,再前序遍历左子树,再前序遍历右子树
8+
- **中序遍历**:先中序遍历左子树,**再访问根节点**,再中序遍历右子树
9+
- **后序遍历**:先后序遍历左子树,再后序遍历右子树,**再访问根节点**
1010

11-
注意点
11+
注意点
1212

1313
- 以根访问顺序决定是什么遍历
1414
- 左子树都是优先右子树
@@ -45,7 +45,10 @@ def postorder_rec(root):
4545

4646
#### [前序非递归](https://leetcode-cn.com/problems/binary-tree-preorder-traversal/)
4747

48-
- 本质上是图的DFS的一个特例,因此可以用栈来实现
48+
- 本质上是图的DFS的一个特例,因此可以用栈来实现。前中后序遍历都是DFS的一种。
49+
- 理解的时候,左右指的不是左右节点,而是左右子树。
50+
- 递归的实现方法都可以使用栈来实现。递归在编程语言中的实现本身也是基于栈的“函数调用栈”。
51+
- 参考:[关于二叉树,你该了解这些!| 二叉树理论基础一网打尽,二叉树的种类、二叉树的存储方式、二叉树节点定义、二叉树的遍历顺序](https://www.bilibili.com/video/BV1Hy4y1t7ij)
4952

5053
```Python
5154
class Solution:
@@ -133,6 +136,45 @@ class Solution:
133136

134137
> DFS 深度搜索(从上到下) 和分治法区别:前者一般将最终结果通过指针参数传入,后者一般递归返回结果最后合并
135138
139+
#### 非递归二叉树通用遍历模板
140+
141+
[颜色标记法,一种通用且简明的树遍历方法](https://leetcode.cn/problems/binary-tree-inorder-traversal/solutions/25220/yan-se-biao-ji-fa-yi-chong-tong-yong-qie-jian-ming)
142+
[迭代的核心思想是采用栈模拟递归](https://leetcode.cn/problems/binary-tree-inorder-traversal/solutions/25220/yan-se-biao-ji-fa-yi-chong-tong-yong-qie-jian-ming/comments/2347570)
143+
[方法还可以优化](https://leetcode.cn/problems/binary-tree-inorder-traversal/solutions/25220/yan-se-biao-ji-fa-yi-chong-tong-yong-qie-jian-ming/comments/204119)
144+
145+
迭代的核心思想是采用栈模拟递归。对于任意一棵树,都将其抽象为(左子树,中节点,右子树),也可以简称为左-中-右三个 "节点"。
146+
147+
遍历一棵树时,按照递归的思路理解,分为 进入 和 回溯 两个阶段,用栈模拟可以理解为 "两次入栈"。 以中序遍历为例:
148+
149+
- 第一次入栈时是以当前节点为根节点的**整棵子树**入栈;
150+
- 通过栈中序遍历该子树,就要对其进行**展开**,第二次入栈代表展开。对于任意一棵树,中序遍历都是先递归左子树,因此需要按照**右子树-中节点-左子树**的顺序入栈展开;
151+
152+
两次入栈就同样对应着两次出栈:
153+
154+
- 第一次出栈是展开前将代表子树的栈顶节点出栈;
155+
- 第二次出栈是展开后栈顶的中节点加入遍历序列;
156+
157+
具体地说,采用变量 flag 标记节点两次入栈的过程,flag = 0 代表第一次入栈,flag = 1 代表第二次入栈。首先根节点标记为 0 入栈,迭代取出栈顶节点时:
158+
159+
- 当栈顶节点的 flag = 0 时,代表子树递归进入的过程,先将栈顶节点出栈,然后按照 右子树-中节点-左子树 的顺序将该子树展开入栈,其中右子树和左子树标记为 0,中节点标记为 1
160+
- 当 flag = 1 时,代表递归回溯的过程,将栈顶节点加入到中序遍历序列
161+
162+
对于python,不需要使用标记。如果栈中是树,则传入节点,如果是值,则传入值。出栈时判断元素类型。
163+
164+
前序遍历的具体代码,其他遍历方式倒着更改入栈顺序就好:
165+
166+
```python
167+
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
168+
stack, values = [root], []
169+
while stack:
170+
node = stack.pop()
171+
if isinstance(node, TreeNode):
172+
stack.extend([node.right, node.left, node.val, ])
173+
elif isinstance(node, int):
174+
values.append(node)
175+
return values
176+
```
177+
136178
#### [BFS 层次遍历](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/)
137179

138180
```Python
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
# 说明
23

34
本项目为原项目 [algorithm-pattern](https://github.com/greyireland/algorithm-pattern) 的 Python3 语言实现版本,原项目使用 go 语言实现,目前已获 ![GitHub stars](https://img.shields.io/github/stars/greyireland/algorithm-pattern?style=social)。在原项目基础上,本项目添加了优先级队列,并查集,图相关算法等内容,基本覆盖了所有基础数据结构和算法,非常适合找工刷题的同学快速上手。以下为原项目 README,目录部分增加了本项目的新内容。
@@ -20,17 +21,17 @@
2021

2122
### 入门篇 🐶
2223

23-
- [使用 Python3 写算法题](./introduction/python.md)
24-
- [算法快速入门](./introduction/quickstart.md)
24+
- [使用 Python3 写算法题](./1.introduction/python.md)
25+
- [算法快速入门](./1.introduction/quickstart.md)
2526

2627
### 数据结构篇 🐰
2728

28-
- [二叉树](./data_structure/binary_tree.md)
29-
- [链表](./data_structure/linked_list.md)
30-
- [栈和队列](./data_structure/stack_queue.md)
31-
- [优先级队列 (堆)](./data_structure/heap.md)
32-
- [并查集](./data_structure/union_find.md)
33-
- [二进制](./data_structure/binary_op.md)
29+
- [二叉树](./2.data_structure/1.binary_tree.md)
30+
- [链表](./2.data_structure/2.linked_list.md)
31+
- [栈和队列](./2.data_structure/3.stack_queue.md)
32+
- [优先级队列 (堆)](./2.data_structure/4.heap.md)
33+
- [并查集](./2.data_structure/5.union_find.md)
34+
- [二进制](./2.data_structure/6.binary_op.md)
3435

3536
### 基础算法篇 🐮
3637

0 commit comments

Comments
 (0)