94. 二叉树的中序遍历
题目要求
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
题解
https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/die-dai-fa-by-jason-2/
关于后序遍历的第二种方法我理解的不是很好,所以采用笨比法认真理解了一遍,感觉理解的不太好又不巧有耐心的读者可以对比着看一下:
为了让注释看得清楚一点,我就用单引号了。
原代码
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> S;
unordered_map<TreeNode*,int> done;
vector<int> v;
TreeNode* rt = root;
while(rt || S.size()){
/ @1
while(rt){
/ @2
S.push(rt);
rt=rt->left;
}
/ cout<<S.top()->val<<" XXX "<<done[S.top()]<<endl
while(S.size() && done[S.top()]){
/ @3
v.push_back(S.top()->val);
S.pop();
}
if(S.size()){
rt=S.top()->right;
/ @4
done[S.top()]=1;
}
}
return v;
}
};
Playground代码
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> S;
unordered_map<TreeNode*,int> done;
vector<int> v;
TreeNode* rt = root;
while(rt || S.size()){
prettyPrintTree(rt);
cout<<"@1 "<<endl;
while(rt){
prettyPrintTree(rt);
cout<<"@2 "<<endl;
S.push(rt);
rt=rt->left;
}
cout<<S.top()->val<<" XXX "<<done[S.top()]<<endl;
while(S.size() && done[S.top()]){
cout<<"@3 "<<done[S.top()]<<endl;
v.push_back(S.top()->val);
S.pop();
}
if(S.size()){
rt=S.top()->right;
cout<<"@4 "<<endl;
done[S.top()]=1;
}
}
return v;
}
};
输出结果
│ ┌── 7
│ ┌── 3
│ │ └── 6
└── 1
│ ┌── 5
└── 2
└── 4
@1
│ ┌── 7
│ ┌── 3
│ │ └── 6
└── 1
│ ┌── 5
└── 2
└── 4
@2
│ ┌── 5
└── 2
└── 4
@2
└── 4
@2
4 XXX 0
@4
Empty tree@1
4 XXX 1
@3 1
@4
└── 5
@1
└── 5
@2
5 XXX 0
@4
Empty tree@1
5 XXX 1
@3 1
@3 1
@4
│ ┌── 7
└── 3
└── 6
@1
│ ┌── 7
└── 3
└── 6
@2
└── 6
@2
6 XXX 0
@4
Empty tree@1
6 XXX 1
@3 1
@4
└── 7
@1
└── 7
@2
7 XXX 0
@4
Empty tree@1
7 XXX 1
@3 1
@3 1
@3 1
[4, 5, 2, 6, 7, 3, 1]
顺便再稍微注释一下。
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> S;
unordered_map<TreeNode*,int> done; / 用unordered_map来储存节点是否被遍历过了
vector<int> v;
TreeNode* rt = root;
while(rt || S.size()){
/ 找到最左节点
while(rt){
S.push(rt);
rt=rt->left;
}
/ 第一轮是跳过这个部分的,直到确定已经遍历完了最左节点之后(done[S.top()]=1)才进入循环
while(S.size() && done[S.top()]){
v.push_back(S.top()->val);
S.pop();
}
/ 当前S.top()的左子树已经遍历完,准备转向右子树,并准备输出中间节点。
if(S.size()){
rt=S.top()->right;
done[S.top()]=1;
}
}
return v;
}
};