-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProblem_0094_inorderTraversal.cc
135 lines (126 loc) · 2.81 KB
/
Problem_0094_inorderTraversal.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <memory>
#include <stack>
#include <type_traits>
#include <vector>
#include "UnitTest.h"
using namespace std;
struct TreeNode
{
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
class Solution
{
public:
void f(TreeNode* node, vector<int>& ans)
{
if (node == nullptr)
{
return;
}
f(node->left, ans);
ans.push_back(node->val);
f(node->right, ans);
}
// 递归
vector<int> inorderTraversal1(TreeNode* root)
{
vector<int> ans;
f(root, ans);
return ans;
}
// 迭代
vector<int> inorderTraversal2(TreeNode* root)
{
if (root == nullptr)
{
return {};
}
vector<int> ans;
stack<TreeNode*> st;
TreeNode* cur = root;
while (!st.empty() || cur != nullptr)
{
if (cur != nullptr)
{
// 先把所有左孩子全部入栈
st.push(cur);
cur = cur->left;
}
else
{
cur = st.top();
st.pop();
// 出栈的时候处理根节点
ans.push_back(cur->val);
// 再处理右孩子,把所有右孩子入栈
cur = cur->right;
}
}
return ans;
}
// Morris遍历
// 把空间复杂度优化到O(1)的二叉树遍历算法
vector<int> inorderTraversal3(TreeNode* root)
{
vector<int> ans;
if (root == nullptr)
{
return ans;
}
TreeNode* cur = root;
TreeNode* mostRight = nullptr;
while (cur != nullptr)
{
mostRight = cur->left;
if (mostRight != nullptr) // 存在左孩子
{
while (mostRight->right != nullptr && mostRight->right != cur)
{
// 找到左孩子最右的节点
mostRight = mostRight->right;
}
if (mostRight->right == nullptr)
{
// 第一次遍历到该节点
// 把这个指针指向当前节点
mostRight->right = cur;
// 遍历左孩子
cur = cur->left;
continue;
}
else
{
// 第二次遍历恢复为叶子节点
mostRight->right = nullptr;
}
}
// 根
ans.push_back(cur->val);
// 左孩子、根都遍历结束,轮到右孩子了
cur = cur->right;
}
return ans;
}
};
void testInorderTraversal()
{
Solution s;
vector<int> o1 = {1, 3, 2};
TreeNode* x3 = new TreeNode(3);
TreeNode* x2 = new TreeNode(2, x3, nullptr);
TreeNode* x1 = new TreeNode(1, nullptr, x2);
EXPECT_TRUE(o1 == s.inorderTraversal1(x1));
EXPECT_TRUE(o1 == s.inorderTraversal2(x1));
EXPECT_TRUE(o1 == s.inorderTraversal3(x1));
EXPECT_SUMMARY;
}
int main()
{
testInorderTraversal();
return 0;
}