1.二叉树前中后序遍历简介
前序遍历:先访问根节点,再访问左节点,最后访问右节点
中序遍历:先访问左节点,再访问根节点,最后访问右节点
后续遍历:先访问左节点,再访问右节点,最后访问根节点
2.递归的方法去实现
深度搜索二叉树的方法:先遍历左子树再遍历右子树
void dfs(TreeNode* root)
{
if(root->left)
dfs(root->left);
if(root->right)
dfs(root->right);
}
那么遍历的顺序确定了,每种遍历方式其实就是访问的位置在哪了(我们只需要关系根节点的访问顺序)
前序遍历:先访问根节点,所以在遍历前访问即可:
void dfs(TreeNode* root)
{
cout<<root->val<<endl;//访问
if(root->left)
dfs(root->left);
if(root->right)
dfs(root->right);
}
中序遍历:先访问左节点,所以在左节点遍历后访问即可:
void dfs(TreeNode* root)
{
if(root->left)
dfs(root->left);
cout<<root->val<<endl;//访问
if(root->right)
dfs(root->right);
}
后序遍历:先访问左节点,再访问右节点,所以在左右节点遍历后访问即可
void dfs(TreeNode* root)
{
if(root->left)
dfs(root->left);
if(root->right)
dfs(root->right);
cout<<root->val<<endl;//访问
}
3.递推的方式去实现
其实一般用递归写的都能递推去实现;
递推的话就用栈去模拟函数开辟子函数的过程,只有当子函数全部执行结束,父函数才会继续执行;这符合栈的后进先出的道理。那么我们将进栈当作遍历左右子树的过程,再确定访问顺序即可。
栈用来存储根节点和左节点。
前序遍历:先访问根节点,再访问左节点,所以在遍历前访问即可;用递推的话就是在其进栈前访问
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> nums;
stack<TreeNode*> s;
while(root||!s.empty())
{
if(!root)
{
root=s.top();
s.pop();
root=root->right;//遍历右子树
}
else
{
while(root)
{
nums.push_back(root->val);//访问
s.push(root);
root=root->left;//遍历左子树
}
}
}
return nums;
}
};
中序遍历:先访问左节点,再访问根节点,所以在左节点遍历后访问即可;用递推的话就是出栈时访问
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> nums;
stack<TreeNode*> s;
while(root||!s.empty())
{
if(!root)
{
root=s.top();
s.pop();
nums.push_back(root->val);
root=root->right;
}
else
{
while(root)
{
s.push(root);
root=root->left;
}
}
}
return nums;
}
};
后序遍历:先访问左节点,再访问右节点,所以在左右节点遍历后访问即可;递推就要为其加一个判断条件,判断其右节点是否访问过,记录上一个访问节点即可(该节点的上一个访问节点必然是其右节点(存在,不存在就是NULL));
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> nums;
stack<TreeNode*> s;
TreeNode *pre=nullptr;//记录上一个访问的节点
while(root||!s.empty())
{
if(!root)
{
root=s.top();
s.pop();
if(!root->right||root->right==pre)//没有右节点或者右节点访问过
{
nums.push_back(root->val);
pre=root;
root=nullptr;
}
else
{
s.push(root);//右节点没访问回到栈中
root=root->right;
}
}
else
{
while(root)
{
s.push(root);
root=root->left;
}
}
}
return nums;
}
};