Skip to content

Commit 384e4f9

Browse files
committed
Binary Tree Postorder Traversal
1 parent ca2eb3e commit 384e4f9

File tree

7 files changed

+413
-0
lines changed

7 files changed

+413
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@
4141
+ [98 Validate Binary Search Tree(BST, 中序遍历)](algorithms/ValidateBinarySearchTree)
4242
+ [100 Same Tree(相同树,遍历)](algorithms/SameTree)
4343
+ [101 Symmetric Tree(对称树)](algorithms/SymmetricTree)
44+
+ [102 Binary Tree Level Order Traversal(层次遍历)](algorithms/BinaryTreeLevelOrderTraversal)
4445
+ [104 Maximum Depth of Binary Tree(树深度)](algorithms/MaximumDepthofBinaryTree)
46+
+ [107 Binary Tree Level Order Traversal II(层次遍历)](algorithms/BinaryTreeLevelOrderTraversal2)
4547
+ [110 Balanced Binary Tree(平衡树)](algorithms/BalancedBinaryTree)
4648
+ [111 Minimum Depth of Binary Tree](algorithms/MinimumDepthofBinaryTree)
4749
+ [112 Path Sum(前序遍历)](algorithms/PathSum)
@@ -53,6 +55,7 @@
5355
+ [141 Linked List Cycle(快慢指针法)](algorithms/LinkedListCycle)
5456
+ [142 Linked List Cycle II](algorithms/LinkedListCycle2)
5557
+ [144 Binary Tree Preorder Traversal(迭代法前序遍历](algorithms/BinaryTreePreorderTraversal)
58+
+ [145 Binary Tree Postorder Traversal(后序遍历)](algorithms/BinaryTreePostorderTraversal)
5659
+ [146 LRU Cache(空间换时间)](algorithms/LRUCache)
5760
+ [147 Insertion Sort List(链表操作,插入排序)](algorithms/InsertionSortList)
5861
+ [150 Evaluate Reverse Polish Notation(栈的应用)](algorithms/EvaluateReversePolishNotation)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## Binary Tree Level Order Traversal
2+
3+
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
4+
5+
For example:
6+
Given binary tree `{3,9,20,#,#,15,7}`,
7+
```
8+
3
9+
/ \
10+
9 20
11+
/ \
12+
15 7
13+
```
14+
return its level order traversal as:
15+
```
16+
[
17+
[3],
18+
[9,20],
19+
[15,7]
20+
]
21+
```
22+
confused what "`{1,#,2,3}`" means? > read more on how binary tree is serialized on OJ.
23+
24+
## Solution
25+
26+
27+
层次遍历,使用队列。
28+
29+
需要保存层次,因此封装了一个桶用于保存处于的层次
30+
```cpp
31+
vector<vector<int>> levelOrder(TreeNode *root) {
32+
vector<vector<int>> result;
33+
if (root == nullptr)
34+
return result;
35+
queue<Bucket> q;
36+
result.push_back(vector<int>());
37+
int curLevel = 0;
38+
q.push(Bucket(root, 0));
39+
while (!q.empty()) {
40+
Bucket bucket = q.front();
41+
q.pop();
42+
TreeNode *p = bucket.node;
43+
int level = bucket.level;
44+
if (level != curLevel) {
45+
result.push_back(vector<int>());
46+
curLevel++;
47+
}
48+
result[curLevel].push_back(p->val);
49+
if (p->left)
50+
q.push(Bucket(p->left, level + 1));
51+
if (p->right)
52+
q.push(Bucket(p->right, level + 1));
53+
}
54+
return result;
55+
}
56+
```
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <string>
4+
#include <algorithm>
5+
#include <cstdio>
6+
#include <queue>
7+
#include <stack>
8+
using namespace std;
9+
struct TreeNode {
10+
int val;
11+
TreeNode *left;
12+
TreeNode *right;
13+
TreeNode(int x) : val(x), left(nullptr), right(nullptr){}
14+
};
15+
struct Bucket {
16+
TreeNode *node;
17+
int level;
18+
Bucket(TreeNode *p, int l) : node(p), level(l){}
19+
};
20+
class Solution {
21+
public:
22+
vector<vector<int>> levelOrder(TreeNode *root) {
23+
vector<vector<int>> result;
24+
if (root == nullptr)
25+
return result;
26+
queue<Bucket> q;
27+
result.push_back(vector<int>());
28+
int curLevel = 0;
29+
q.push(Bucket(root, 0));
30+
while (!q.empty()) {
31+
Bucket bucket = q.front();
32+
q.pop();
33+
TreeNode *p = bucket.node;
34+
int level = bucket.level;
35+
if (level != curLevel) {
36+
result.push_back(vector<int>());
37+
curLevel++;
38+
}
39+
result[curLevel].push_back(p->val);
40+
if (p->left)
41+
q.push(Bucket(p->left, level + 1));
42+
if (p->right)
43+
q.push(Bucket(p->right, level + 1));
44+
}
45+
return result;
46+
}
47+
};
48+
TreeNode *mk_node(int val)
49+
{
50+
return new TreeNode(val);
51+
}
52+
TreeNode *mk_child(TreeNode *root, TreeNode *left, TreeNode *right)
53+
{
54+
root->left = left;
55+
root->right = right;
56+
return root;
57+
}
58+
TreeNode *mk_child(TreeNode *root, int left, int right)
59+
{
60+
return mk_child(root, new TreeNode(left), new TreeNode(right));
61+
}
62+
TreeNode *mk_child(int root, int left, int right)
63+
{
64+
return mk_child(new TreeNode(root), new TreeNode(left), new TreeNode(right));
65+
}
66+
int main(int argc, char **argv)
67+
{
68+
Solution solution;
69+
TreeNode *root = mk_child(1, 2, 3);
70+
mk_child(root->left, 4, 5);
71+
auto results = solution.levelOrder(root);
72+
for (auto result : results) {
73+
for_each(result.begin(), result.end(), [](int i){cout << i << " ";});
74+
cout << endl;
75+
}
76+
return 0;
77+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
## Binary Tree Level Order Traversal II
2+
3+
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
4+
5+
For example:
6+
Given binary tree `{3,9,20,#,#,15,7}`,
7+
```
8+
3
9+
/ \
10+
9 20
11+
/ \
12+
15 7
13+
```
14+
return its bottom-up level order traversal as:
15+
```
16+
[
17+
[15,7],
18+
[9,20],
19+
[3]
20+
]
21+
```
22+
confused what "`{1,#,2,3}`" means? > read more on how binary tree is serialized on OJ.
23+
24+
## Solution
25+
26+
思路就是常规的BFS,然后把结果reverse ?
27+
28+
应该还有其他更优算法?
29+
```cpp
30+
vector<vector<int>> levelOrderBottom(TreeNode *root) {
31+
vector<vector<int>> result;
32+
if (root == nullptr)
33+
return result;
34+
queue<Bucket> q;
35+
result.push_back(vector<int>());
36+
int curLevel = 0;
37+
q.push(Bucket(root, 0));
38+
while (!q.empty()) {
39+
Bucket bucket = q.front();
40+
q.pop();
41+
TreeNode *p = bucket.node;
42+
int level = bucket.level;
43+
if (level != curLevel) {
44+
result.push_back(vector<int>());
45+
curLevel++;
46+
}
47+
result[curLevel].push_back(p->val);
48+
if (p->left)
49+
q.push(Bucket(p->left, level + 1));
50+
if (p->right)
51+
q.push(Bucket(p->right, level + 1));
52+
}
53+
reverse(result.begin(), result.end());
54+
}
55+
```
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <string>
4+
#include <algorithm>
5+
#include <cstdio>
6+
#include <queue>
7+
#include <stack>
8+
using namespace std;
9+
struct TreeNode {
10+
int val;
11+
TreeNode *left;
12+
TreeNode *right;
13+
TreeNode(int x) : val(x), left(nullptr), right(nullptr){}
14+
};
15+
struct Bucket {
16+
TreeNode *node;
17+
int level;
18+
Bucket(TreeNode *p, int l) : node(p), level(l){}
19+
};
20+
class Solution {
21+
public:
22+
vector<vector<int>> levelOrderBottom(TreeNode *root) {
23+
vector<vector<int>> result;
24+
if (root == nullptr)
25+
return result;
26+
queue<Bucket> q;
27+
result.push_back(vector<int>());
28+
int curLevel = 0;
29+
q.push(Bucket(root, 0));
30+
while (!q.empty()) {
31+
Bucket bucket = q.front();
32+
q.pop();
33+
TreeNode *p = bucket.node;
34+
int level = bucket.level;
35+
if (level != curLevel) {
36+
result.push_back(vector<int>());
37+
curLevel++;
38+
}
39+
result[curLevel].push_back(p->val);
40+
if (p->left)
41+
q.push(Bucket(p->left, level + 1));
42+
if (p->right)
43+
q.push(Bucket(p->right, level + 1));
44+
}
45+
reverse(result.begin(), result.end());
46+
}
47+
};
48+
TreeNode *mk_node(int val)
49+
{
50+
return new TreeNode(val);
51+
}
52+
TreeNode *mk_child(TreeNode *root, TreeNode *left, TreeNode *right)
53+
{
54+
root->left = left;
55+
root->right = right;
56+
return root;
57+
}
58+
TreeNode *mk_child(TreeNode *root, int left, int right)
59+
{
60+
return mk_child(root, new TreeNode(left), new TreeNode(right));
61+
}
62+
TreeNode *mk_child(int root, int left, int right)
63+
{
64+
return mk_child(new TreeNode(root), new TreeNode(left), new TreeNode(right));
65+
}
66+
int main(int argc, char **argv)
67+
{
68+
Solution solution;
69+
TreeNode *root = mk_child(1, 2, 3);
70+
mk_child(root->left, 4, 5);
71+
auto results = solution.levelOrderBottom(root);
72+
for (auto result : results) {
73+
for_each(result.begin(), result.end(), [](int i){cout << i << " ";});
74+
cout << endl;
75+
}
76+
return 0;
77+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
## Binary Tree Postorder Traversal
2+
3+
Given a binary tree, return the postorder traversal of its nodes' values.
4+
5+
For example:
6+
Given binary tree {1,#,2,3},
7+
```
8+
1
9+
\
10+
2
11+
/
12+
3
13+
```
14+
return [3,2,1].
15+
16+
## Solution 1
17+
18+
递归法, 这个方法没有什么难度
19+
20+
## Solution 2
21+
22+
前序遍历,然后把结果reverse
23+
24+
## Solution 3
25+
26+
根据后序遍历的方式,最先访问的是左孩子节点的最左的最后一个节点,比如
27+
28+
```
29+
30+
1
31+
/ \
32+
2 3
33+
/ \
34+
5 4
35+
\ \
36+
6 7
37+
```
38+
显然最先访问的是6,因此需要把之前的节点压入栈。
39+
```cpp
40+
void pushLeftOrRight(TreeNode *p, stack<TreeNode*> &s) {
41+
while (p) {
42+
s.push(p);
43+
p = p->left != nullptr ? p->left : p->right;
44+
}
45+
}
46+
```
47+
48+
显然先是从root开始,压入的顺序依次为`1 2 5 6`
49+
50+
然后依次出栈就是访问顺序,当出栈前需要判断是否还有右孩子没有访问
51+
52+
比如当前已访问2(2还没有出栈),应该开始访问右孩子, 即调用`pushLeftOrRight(p->right, s)`
53+
54+
那怎么知道有没有访问右孩子呢?我们发现我们有两次机会会到达2,一次是访问完左孩子,一次是访问完右孩子,即访问完5和4
55+
56+
我们可以发现,只要2出栈前,看之前访问的是否是左孩子即可,若是左孩子,说明右孩子没有访问
57+
```cpp
58+
vector<int> postorderTraversal(TreeNode *root) {
59+
vector<int> result;
60+
if (root == nullptr)
61+
return result;
62+
stack<TreeNode*>s;
63+
pushLeftOrRight(root, s);
64+
while (!s.empty()) {
65+
TreeNode *p = getAndPop(s); // s.top(), s.pop()
66+
result.push_back(p->val);
67+
TreeNode *next = s.empty() ? nullptr : s.top();
68+
if (next && next->left == p)
69+
pushLeftOrRight(next->right, s);
70+
}
71+
return result;
72+
}
73+
```

0 commit comments

Comments
 (0)