# Definition for binary tree
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
1. 先序遍历
1.1 先序遍历的递归版本
根->左->右
class Solution {
public:
vector<int> res;
vector<int> preorderTraversal(TreeNode *root) {
if(root)
preorder(root);
return res;
}
void preorder(TreeNode *root){
if(!root) return;
res.push_back(root->val);
preorder(root->left);
preorder(root->right);
}
}
1.2 前序遍历非递归版本
- 先将根节点进栈
- 在栈不空时循环:
2.1 访问栈顶元素*p
节点
2.2 栈顶元素*p
出栈
2.3 若其右孩子节点不空,将右孩子节点进栈
2.4 若其左孩子节点不空,将左孩子节点进栈
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> res;
if(!root) return res;
stack<TreeNode *>stk;
TreeNode *t;
stk.push(root);
while(!stk.empty()){
t=stk.top();
stk.pop();
res.push_back(t->val);
if(t->right)
stk.push(t->right);
if(t->left)
stk.push(t->left);
}
return res;
}
};
2. 后序遍历
2.1 后序遍历的递归版本
左->右->根
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if(!root) return res;
postorder(root,res);
return res;
}
void postorder(TreeNode *root,vector<int> &v) {
if(!root) return ;
postorder(root->left,v);
postorder(root->right,v);
v.push_back(root->val);
}
};
2.2 后序遍历的非递归版本
巧妙的方法:参考前序遍历
- 前序遍历 根->左->右 改为 根->右->左 (进栈顺序交换左右孩子节点)
- 结果再reverse即为左->右->根
- 先将根节点进栈
- 在栈不空时循环:
2.1 访问栈顶元素*p
节点
2.2 栈顶元素*p
出栈
2.3 若其左孩子节点不空将左孩子节点进栈
2.4 若其右孩子节点不空将右孩子节点进栈 - 结果翻转
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if(!root) return res;
stack<TreeNode *>stk;
stk.push(root);
TreeNode *t;
while(!stk.empty()){
t=stk.top();
stk.pop();
res.push_back(t->val);
if(t->left)
stk.push(t->left);
if(t->right)
stk.push(t->right);
}
reverse(res.begin(),res.end());
return res;
}
};
3. 中序遍历
3.1 中序遍历的递归版本
左->根->右
class Solution {
public:
vector<int> res;
vector<int> inorderTraversal(TreeNode *root) {
if(!root) return res;
inorder(root);
return res;
}
void inorder(TreeNode *root){
if(!root) return;
inorder(root->left);
res.push_back(root->val);
inorder(root->right);
}
};
3.2 中序遍历的非递归版本
采用一个栈来保存需要返回的节点指针
- 用指针
*p
指向当前要处理的节点 - 先扫描(并非访问)该节点的所有左节点,并将它们一一进栈
- 当无左节点时,出栈栈顶节点
t
,并访问它 - 将
p
指向t
的右孩子,对右子树进行同样的处理
当节点*p
的所有左下节点进栈后,这时的栈顶节点t
要么没有左子树,要么左子树已经访问过,就可以访问这个栈顶节点t
。如此重复循环,直到栈空为止。
class Solution {
public:
vector<int> res;
vector<int> inorderTraversal(TreeNode *root) {
if(!root) return res;
stack<TreeNode *> stk;
TreeNode *t,*p=root;
while(p || !stk.empty()){
while(p){
stk.push(p);
p=p->left;
}
if(!stk.empty()){
t=stk.top();
stk.pop();
res.push_back(t->val);
p=t->right;
}
}
return res;
}
};