Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6c2e5a0

Browse files
committed
二叉树的统一迭代法.md 为"boolean标记法"加上C++的实现代码
1 parent 0c80ec2 commit 6c2e5a0

File tree

1 file changed

+77
-2
lines changed

1 file changed

+77
-2
lines changed

‎problems/二叉树的统一迭代法.md‎

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
### 迭代法中序遍历
3838

39-
中序遍历代码如下:(详细注释)
39+
> 中序遍历(空指针标记法)代码如下:(详细注释)
4040
4141
```CPP
4242
class Solution {
@@ -75,6 +75,45 @@ public:
7575

7676
可以看出我们将访问的节点直接加入到栈中,但如果是处理的节点则后面放入一个空节点, 这样只有空节点弹出的时候,才将下一个节点放进结果集。
7777

78+
> 中序遍历(boolean 标记法):
79+
```c++
80+
class Solution {
81+
public:
82+
vector<int> inorderTraversal(TreeNode* root) {
83+
vector<int> result;
84+
stack<pair<TreeNode*, bool>> st;
85+
if (root != nullptr)
86+
st.push(make_pair(root, false)); // 多加一个参数,false 为默认值,含义见下文注释
87+
88+
while (!st.empty()) {
89+
auto node = st.top().first;
90+
auto visited = st.top().second; //多加一个 visited 参数,使"迭代统一写法"成为一件简单的事
91+
st.pop();
92+
93+
if (visited) { // visited 为 True,表示该节点和两个儿子位次之前已经安排过了,现在可以收割节点了
94+
result.push_back(node->val);
95+
continue;
96+
}
97+
98+
// visited 当前为 false, 表示初次访问本节点,此次访问的目的是"把自己和两个儿子在栈中安排好位次"。
99+
100+
// 中序遍历是'左中右',右儿子最先入栈,最后出栈。
101+
if (node->right)
102+
st.push(make_pair(node->right, false));
103+
104+
// 把自己加回到栈中,位置居中。
105+
// 同时,设置 visited 为 true,表示下次再访问本节点时,允许收割。
106+
st.push(make_pair(node, true));
107+
108+
if (node->left)
109+
st.push(make_pair(node->left, false)); // 左儿子最后入栈,最先出栈
110+
}
111+
112+
return result;
113+
}
114+
};
115+
```
116+
78117
此时我们再来看前序遍历代码。
79118

80119
### 迭代法前序遍历
@@ -110,7 +149,7 @@ public:
110149
111150
### 迭代法后序遍历
112151
113-
后续遍历代码如下: (**注意此时我们和中序遍历相比仅仅改变了两行代码的顺序**)
152+
> 后续遍历代码如下: (**注意此时我们和中序遍历相比仅仅改变了两行代码的顺序**)
114153
115154
```CPP
116155
class Solution {
@@ -141,6 +180,42 @@ public:
141180
};
142181
```
143182

183+
> 迭代法后序遍历(boolean 标记法):
184+
```c++
185+
class Solution {
186+
public:
187+
vector<int> postorderTraversal(TreeNode* root) {
188+
vector<int> result;
189+
stack<pair<TreeNode*, bool>> st;
190+
if (root != nullptr)
191+
st.push(make_pair(root, false)); // 多加一个参数,false 为默认值,含义见下文
192+
193+
while (!st.empty()) {
194+
auto node = st.top().first;
195+
auto visited = st.top().second; //多加一个 visited 参数,使"迭代统一写法"成为一件简单的事
196+
st.pop();
197+
198+
if (visited) { // visited 为 True,表示该节点和两个儿子位次之前已经安排过了,现在可以收割节点了
199+
result.push_back(node->val);
200+
continue;
201+
}
202+
203+
// visited 当前为 false, 表示初次访问本节点,此次访问的目的是"把自己和两个儿子在栈中安排好位次"。
204+
// 后序遍历是'左右中',节点自己最先入栈,最后出栈。
205+
// 同时,设置 visited 为 true,表示下次再访问本节点时,允许收割。
206+
st.push(make_pair(node, true));
207+
208+
if (node->right)
209+
st.push(make_pair(node->right, false)); // 右儿子位置居中
210+
211+
if (node->left)
212+
st.push(make_pair(node->left, false)); // 左儿子最后入栈,最先出栈
213+
}
214+
215+
return result;
216+
}
217+
};
218+
```
144219
## 总结
145220

146221
此时我们写出了统一风格的迭代法,不用在纠结于前序写出来了,中序写不出来的情况了。

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /