二叉树前序遍历:先访问根结点,然后右子树入栈,最后左子树入栈;
#define mp make_pair
class Solution {
public:
int maxDepth(TreeNode* root){
stack<pair<TreeNode*,int> >s;
s.push(mp(root,1));
int max_dep=0;
while(!s.empty()){
TreeNode*p=s.top().first;
int dep=s.top().second;
s.pop();
if(p==NULL) continue;
max_dep=max(max_dep,dep);
s.push(mp(p->right,dep+1));
s.push(mp(p->left,dep+1));
}
return max_dep;
}
};
二叉树中序遍历:
1、从当前(根)结点开始入栈,指针移向左子树,一直到没有左子树的节点结束入栈;
2、访问栈顶元素,然后当前节点右子树,再次从步骤1开始;
3、当栈为空且指针指向NULL时,访问结束。
#define mp make_pair
class Solution {
public:
int maxDepth(TreeNode* root){
stack<pair<TreeNode*,int> >s;
int dep=1;
int max_dep=0;
TreeNode *p=root;
while(!s.empty()||p!=NULL){
while(p!=NULL){
s.push(mp(p,dep));
++dep;
p=p->left;
}
p=s.top().first;
dep=s.top().second;
s.pop();
max_dep=max(max_dep,dep);
p=p->right;
++dep;
}
return max_dep;
}
};
后序遍历:后序遍历的难点在于如何判断当前节点的左右子树都已经访问过了,解决方法是标记最近访问过的右子树;对于栈顶元素,判断当前节点的右子树是否为空或者是最近访问过的。
#define mp make_pair
class Solution {
public:
int maxDepth(TreeNode* root){
stack<pair<TreeNode*,int> >s;
int dep=1;
int max_dep=0;
TreeNode *p=root,*r=NULL;
while(p||!s.empty()){
while(p!=NULL){
s.push(mp(p,dep));
++dep;
p=p->left;
}
p=s.top().first;
dep=s.top().second;
if(p->right==NULL||p->right==r){
s.pop();
max_dep=max(max_dep,dep);
r=p;
p=NULL;
}
else{
p=p->right;
dep++;
}
}
return max_dep;
}
};
或者直接用一个元素记录每个元素的访问状态;
#define mp make_pair
class Solution {
public:
int maxDepth(TreeNode* root){
stack<pair<TreeNode*,int> >s;
stack<int>smark;
int dep=1;
int max_dep=0;
TreeNode *p=root,*r=NULL;
while(p||!s.empty()){
while(p!=NULL){
s.push(mp(p,dep));
smark.push(0);
++dep;
p=p->left;
}
p=s.top().first;
dep=s.top().second;
if(smark.top()==1){
s.pop();
smark.pop();
max_dep=max(max_dep,dep);
p=NULL;
}
else{
p=p->right;
smark.top()=1;
dep++;
}
}
return max_dep;
}
};