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 4034b05

Browse files
data_structure
0 parents commit 4034b05

12 files changed

+3673
-0
lines changed

‎data_structure/二叉树.md

Lines changed: 404 additions & 0 deletions
Large diffs are not rendered by default.

‎data_structure/二叉树和二叉搜索树.md

Lines changed: 496 additions & 0 deletions
Large diffs are not rendered by default.

‎data_structure/二叉树的遍历.md

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
### 二叉树的前中后序遍历(递归)
2+
#### 前序遍历
3+
```
4+
vector <int> res;
5+
6+
vector<int> main(TreeNode* root){
7+
dfs(root);
8+
return res;
9+
}
10+
11+
void dfs(TreeNode* root){
12+
if (!root) return;
13+
res.push_back(root->val);
14+
dfs(root->left);
15+
dfs(root->right);
16+
}
17+
```
18+
#### 中序遍历
19+
```
20+
vector <int> res;
21+
22+
vector<int> main(TreeNode* root){
23+
dfs(root);
24+
return res;
25+
}
26+
27+
void dfs(TreeNode* root){
28+
if (!root) return;
29+
dfs(root->left);
30+
res.push_back(root->val);
31+
dfs(root->right);
32+
}
33+
```
34+
#### 后序遍历
35+
```
36+
vector <int> res;
37+
38+
vector<int> main(TreeNode* root){
39+
dfs(root);
40+
return res;
41+
}
42+
43+
void dfs(TreeNode* root){
44+
if (!root) return;
45+
dfs(root->left);
46+
dfs(root->right);
47+
res.push_back(root->val);
48+
}
49+
```
50+
### 二叉树的前中后序遍历(迭代)
51+
#### 前序遍历
52+
- 思路:二叉树的迭代遍历一般用栈来存储
53+
栈是先进后出的顺序,如果是前序遍历,输出为中->左->右,所以先将右儿子入栈,再将左儿子入栈
54+
- 模板解法:
55+
1. 初始化栈
56+
2. 当前节点赋值为根节点
57+
3. 将根节点和所有左孩子入栈并加入答案直至当前节点为空
58+
4. 每弹出一个栈顶元素就到达当前节点的右孩子
59+
- 代码模板
60+
```
61+
stack<TreeNode*> stk;
62+
vector<int> res;
63+
auto cur = root;
64+
while (cur || stk.size()){
65+
while (cur){
66+
res.push_back(cur->val);
67+
stk.push(cur);
68+
cur = cur->left;
69+
}
70+
auto tmp = stk.top();
71+
stk.pop();
72+
cur = tmp->right;
73+
}
74+
```
75+
- 常规解法:
76+
1. 初始化栈
77+
2. 将根节点入栈
78+
3. 当栈不为空将栈顶元素记录弹出加入答案
79+
4. 如果元素有右儿子则将右儿子入栈,如果有左儿子则将左儿子入栈
80+
- 代码模板
81+
```
82+
stack<TreeNode*> stk;
83+
vector<int> res;
84+
if (root) stk.push(root);
85+
while (stk.size()){
86+
auto c = stk.top();
87+
stk.pop();
88+
res.push_back(c->val);
89+
if (c->right) stk.push(c->right);
90+
if (c->left) stk.push(c->left);
91+
}
92+
```
93+
#### 中序遍历
94+
- 思路:与前序遍历的模板解法相似,区别是前序遍历中在找树的左底部的过程中记录答案,而中序遍历是找到左底部再开始记录答案
95+
- 模板解法:
96+
1. 初始化栈
97+
2. 当前节点赋值为根节点
98+
3. 将根节点和所有左孩子入栈直至当前节点为空
99+
4. 每弹出一个栈顶元素加入答案并到达当前节点的右孩子
100+
- 代码模板
101+
```
102+
stack<TreeNode*> stk;
103+
vector<int> res;
104+
auto cur = root;
105+
while (cur || stk.size()){
106+
while (cur){
107+
stk.push(cur);
108+
cur = cur->left;
109+
}
110+
auto temp = stk.top();
111+
stk.pop();
112+
res.push_back(temp->val);
113+
cur = temp->right;
114+
}
115+
```
116+
#### 后序遍历
117+
- 思路:与前序遍历的模板解法类似
118+
栈是先进后出的顺序,如果是后序遍历,输出为左->右->中,和前序遍历中->左->右相比,可以在前序遍历的基础上将输入改为中->右->左,再将答案数组反转即为左->右->中
119+
- 模板解法:
120+
1. 初始化栈
121+
2. 当前节点赋值为根节点
122+
3. 将根节点和所有右孩子入栈并加入答案直至当前节点为空
123+
4. 每弹出一个栈顶元素就到达当前节点的左孩子
124+
5. 反转答案数组
125+
- 代码模板
126+
```
127+
stack<TreeNode*> stk;
128+
vector<int> res;
129+
auto cur = root;
130+
while (cur || stk.size()){
131+
while (cur){
132+
stk.push(cur);
133+
res.push_back(cur->val);
134+
cur = cur->right;
135+
}
136+
auto temp = stk.top();
137+
stk.pop();
138+
cur = temp->left;
139+
}
140+
reverse(res.begin(), res.end());
141+
```
142+
### 二叉树的层序遍历
143+
- 思路:二叉树的前中后序遍历都是用深度优先搜索的方法(dfs)主要使用栈实现,层序遍历是广度优先搜索主要使用队列实现
144+
- 常规解法:
145+
1. 初始化队列
146+
2. 将根节点加入队列中
147+
3. 当队列不为空时,弹出队头元素,加入到答案中
148+
4. 如果左子树非空,左子树加入队列
149+
5. 如果右子树非空,右子树加入队列
150+
- 代码模板
151+
```
152+
queue<TreeNode*> q;
153+
vector<int> res;
154+
q.push(root);
155+
while (q.size()){
156+
int n = q.size();
157+
for (int i = 0; i < n; i ++){
158+
auto cur = q.front();
159+
q.pop();
160+
res.push_back(cur->val);
161+
if (cur->left) q.push(cur->left);
162+
if (cur->right) q.push(cur->right);
163+
}
164+
}
165+
```
166+
### 二叉树有关的题目和二叉树遍历的关系
167+
#### leetcode.226
168+
- 链接<https://leetcode.cn/problems/invert-binary-tree/>
169+
- 解题方法:有三种方法解本道题
170+
从上到下遍历树的时候翻转左右节点->前序遍历
171+
遍历到树的叶子节点回溯的时候翻转左右节点->后序遍历
172+
遍历每一层,将每一层的左右节点翻转->层序遍历
173+
- leetcode解题代码
174+
```
175+
class Solution {
176+
public:
177+
TreeNode* invertTree(TreeNode* root) {
178+
// 递归(终止条件)
179+
if (!root) return root;
180+
// 前序遍历(递归解法)
181+
swap(root->left, root->right);
182+
invertTree(root->left);
183+
invertTree(root->right);
184+
// 递归返回值
185+
return root;
186+
}
187+
};
188+
189+
class Solution {
190+
public:
191+
TreeNode* invertTree(TreeNode* root) {
192+
// 递归(终止条件)
193+
if (!root) return root;
194+
// 后序遍历(递归解法)
195+
invertTree(root->left);
196+
invertTree(root->right);
197+
swap(root->left, root->right);
198+
// 递归返回值
199+
return root;
200+
}
201+
};
202+
203+
class Solution {
204+
public:
205+
TreeNode* invertTree(TreeNode* root) {
206+
// 层序遍历模板
207+
queue<TreeNode*> q;
208+
if (root) q.push(root);
209+
while (q.size()){
210+
int n = q.size();
211+
for (int i = 0; i < n; i ++){
212+
auto c = q.front();
213+
q.pop();
214+
swap(c->left, c->right);
215+
if (c->left) q.push(c->left);
216+
if (c->right) q.push(c->right);
217+
}
218+
}
219+
return root;
220+
}
221+
};
222+
```
223+
#### leetcode.589
224+
- 链接<https://leetcode.cn/problems/n-ary-tree-preorder-traversal/>
225+
- 解题方法:前序遍历递归模板或前序遍历迭代常规解法模板
226+
- leetcode解题代码
227+
```
228+
class Solution {
229+
public:
230+
vector<int> res;
231+
vector<int> preorder(Node* root) {
232+
// 递归终止条件
233+
if (!root) return res;
234+
// 前序遍历
235+
res.push_back(root->val);
236+
for (auto c: root->children) preorder(c);
237+
return res;
238+
}
239+
};
240+
241+
class Solution {
242+
public:
243+
vector<int> preorder(Node* root) {
244+
// 与前序遍历常规解法相似
245+
stack<Node*> stk;
246+
vector<int> res;
247+
if (root) stk.push(root);
248+
while (stk.size()){
249+
auto c = stk.top();
250+
stk.pop();
251+
res.push_back(c->val);
252+
for (int i = c->children.size() - 1; i >= 0; i --){
253+
stk.push(c->children[i]);
254+
}
255+
}
256+
return res;
257+
}
258+
};
259+
```
260+
#### leetcode.590
261+
- 链接<https://leetcode.cn/problems/n-ary-tree-postorder-traversal/>
262+
- 解题方法:后序遍历递归模板或后序遍历迭代常规解法模板
263+
- leetcode解题代码
264+
```
265+
class Solution {
266+
public:
267+
vector<int> res;
268+
vector<int> postorder(Node* root) {
269+
// 递归终止条件
270+
if (!root) return res;
271+
// 后序遍历
272+
for (auto c: root->children) postorder(c);
273+
res.push_back(root->val);
274+
return res;
275+
}
276+
};
277+
278+
class Solution {
279+
public:
280+
vector<int> postorder(Node* root) {
281+
// 与后序遍历常规解法类似
282+
stack<Node*> stk;
283+
vector<int> res;
284+
if (root) stk.push(root);
285+
while (stk.size()){
286+
auto c = stk.top();
287+
stk.pop();
288+
res.push_back(c->val);
289+
for (int i = 0; i < c->children.size(); i ++){
290+
stk.push(c->children[i]);
291+
}
292+
}
293+
reverse(res.begin(), res.end());
294+
return res;
295+
}
296+
};
297+
```

0 commit comments

Comments
(0)

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