递归法
比较简单,不详述了。
先序遍历(root→left→right)
LeetCode 144
class Solution {
public:
vector<int> pre;
vector<int> preorderTraversal(TreeNode* root)
{
helper(root);
return pre;
}
void helper(TreeNode *root)
{
if(root==NULL) return;
pre.push_back(root->val);
helper(root->left);
helper(root->right);
}
};
中序遍历(left→root→right)
LeetCode 94
class Solution {
public:
vector<int> inorder;
vector<int> inorderTraversal(TreeNode* root)
{
helper(root);
return inorder;
}
void helper(TreeNode *root)
{
if(root==NULL) return;
helper(root->left);
inorder.push_back(root->val);
helper(root->right);
}
};
后序遍历(left→right→root)
LeetCode 145
class Solution {
public:
vector<int> post;
vector<int> postorderTraversal(TreeNode* root) {
helper(root);
return post;
}
void helper(TreeNode *root)
{
if(root==NULL) return;
helper(root->left);
helper(root->right);
post.push_back(root->val);
}
};
迭代法
参考了:这个解法
先序遍历
考虑将递归转化为迭代的办法。
为了更好的理解这一部分,我专门去学习了一波函数调用的原理。简单来说,调用一个函数就是把该函数相关的入口地址信息和局部变量等压栈,然后再通过call命令去执行函数操作。函数执行完毕之后,把相关变量(如果有的话)传递给主函数,然后把之前入栈的那些东西pop掉。
对于递归来说,就是自己调用自己,直到遇到了“递归边界”直接return了,才跟多米诺骨牌似的一溜儿的全出栈了。
了解了原理之后其他的就不难了,在写代码的过程只需要关注局部变量的入栈和出栈。
在迭代中,要做的就是模拟递归的过程,没有栈就创造一个栈出来。对于递归来说,我们的形参是TreeNode* root
,实际上是遍历了二叉树上的全部节点,于是建立一个stack<TreeNode*> st
,用于保存二叉树上的节点。
以前序遍历为例,访问顺序为root→left→right,所以入栈的顺序应该为right→left→root,引入一个NULL来表示在它之前的元素该出栈了。
流程图:
中序遍历和后序遍历与此大致相同。
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> res;
stack<TreeNode*> st;
if(root!=NULL) st.push(root);
while(!st.empty())
{
TreeNode *tmp=st.top();
st.pop();
if(tmp!=NULL)
{
if(tmp->right!=NULL) st.push(tmp->right);
if(tmp->left!=NULL) st.push(tmp->left);
st.push(tmp);
st.push(NULL);//表示该节点访问过
}
else
{
tmp=st.top();
st.pop();
res.push_back(tmp->val);
}
}
return res;
}
};
中序遍历
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> res;
stack<TreeNode*> st;
if(root!=NULL) st.push(root);
while(!st.empty())
{
TreeNode *tmp=st.top();
st.pop();
if(tmp!=NULL)
{
if(tmp->right) st.push(tmp->right);
st.push(tmp);
st.push(NULL);
if(tmp->left) st.push(tmp->left);
}
else
{
tmp=st.top();
res.push_back(tmp->val);
st.pop();
}
}
return res;
}
};
后序遍历
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> res;
stack<TreeNode*> st;
if(root!=NULL) st.push(root);
while(!st.empty())
{
TreeNode* tmp=st.top();
st.pop();
if(tmp!=NULL)
{
st.push(tmp);
st.push(NULL);
if(tmp->right) st.push(tmp->right);
if(tmp->left) st.push(tmp->left);
}
else
{
tmp=st.top();
res.push_back(tmp->val);
st.pop();
}
}
return res;
}
};