二叉树的前中后序遍历。
前序:读取根节点的值并压栈,一直向左找到最左的节点后返回上一层开始向右寻找。
中序:将根节点一直压栈并向左寻找,找到最左的节点后读取该节点的值并返回上一层开始向右寻找。
这两个其实就是读取值的时间有点不一样而已。
后序:后序麻烦一点,输出顺序是左右中,可以通过变量记录当前节点的子树是否已经输出过,一个技巧性的方法是可以设置一个变量记录之前被输出的结点,利用后序遍历父节点的输出一定挨着它的子节点的这一性质,如果之前被输出的结点不是当前节点的右子树且右子树非空的话访问节点右子树,否则输出父节点。
前序:
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode* p=root;
stack<TreeNode* > s;
while(!s.empty()||p){
if(p){
res.push_back(p->val);
s.push(p);
p=p->left;
}
else{
p=s.top();
s.pop();
p=p->right;
}
}
return res;
}
};
中序:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> tree;
TreeNode* p=root;
while(!tree.empty()||p){
if(p){
tree.push(p);
p=p->left;
}
else{
p=tree.top();
res.push_back(p->val);
tree.pop();
p=p->right;
}
}
return res;
}
};
后序:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> s;
TreeNode* p=root, *LastVisit=NULL;
while(true){
while(p){
s.push(p);
p=p->left;
}
if(s.empty()) break;
p=s.top();
if(p->right&&p->right!=LastVisit) p=p->right;
else{
s.pop();
res.push_back(p->val);
LastVisit=p;
p=NULL;
}
}
return res;
}
};