二叉树的遍历主要包括前序遍历、中序遍历、后序遍历和层序遍历四种,其中前三种是非常常用的,下面介绍前三种遍历的方法。
- 前序遍历
思路:从根结点开始遍历,若二叉树为空,则直接返回NULL,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。如下图所示:
代码实现:
前序遍历递归:
class Solution{
public:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> v;
if(root == NULL)
return v;
perOrder(root,v);
return v;
}
void preOrder(TreeNode* root,vector<int> &v)
{
v.push_back(root->val);
if(root->left)
preOrder(root->left,v);
if(root->right)
preOrder(root->right,v);
}
};
前序遍历非递归:
class Solution{
public:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> v;
if(root == NULL)
return v;
stack<TreeNode*> s;
s.push(root);
while(!s.empty())
{
TreeNode* cur = s.top();
s.pop();
v.push_back(cur->val);
if(cur->right)
s.push_back(cur->right);
if(cur->left)
s.push_back(cur->left);
}
return v;
}
};
- 中序遍历
思路:若二叉树为空,则返回NULL,否则从根结点开始(注意不是先访问根结点),中序遍历根结点的左子树,然后访问根结点,最后中序遍历右子树。如下图所示:
代码实现:
中序遍历递归:
class Solution{
public:
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> v;
if (root == NULL)
return v;
inOrder(root, v);
return v;
}
void inOrder(TreeNode* root, vector<int> &v)
{
if (root->left)
inOrder(root->left, v);
v.push_back(root->val);
if (root->right)
inOrder(root->right, v);
}
};
中序遍历非递归遍历:
class Solution{
public:
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> v;
if (root == NULL)
return v;
stack<TreeNode*> s;
s.push(root);
while (!s.empty())
{
TreeNode* cur = s.top();
if (cur->left)
{
s.push(cur->left);
cur->left == NULL;
}
else
{
v.push_back(cur->val);
s.pop();
if (cur->right)
{
s.push(cur->right);
}
}
}
return v;
}
};
- 后序遍历
思路:若二叉树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。如下图所示:
代码实现:
后序遍历递归:
class Solution{
public:
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> v;
if (root == NULL)
return v;
postOrder(root, v);
return v;
}
void postOrder(TreeNode* root, vector<int> &v)
{
if (root->left)
postOrder(root->left, v);
if (root->right)
postOrder(root->right, v);
v.push_back(root->val);
}
};
后序遍历非递归:
class Solution{
public:
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> v;
if (root == NULL)
return v;
stack<TreeNode*> s;
s.push(root);
while (!s.empty())
{
TreeNode* cur = s.top();
if (cur->left == NULL&&cur->right == NULL)
{
v.push_back(cur->val);
s.pop();
}
else
{
if (cur->right)
{
s.push(cur->right);
cur->right = NULL;
}
if (cur->left)
{
s.push(cur->left);
cur->left = NULL;
}
}
}
return v;
}
};
两个二叉树遍历的性质:
1.已知前序遍历和中序遍历,可以唯一的确定一个二叉树;
2.已知后序遍历和中序遍历,可以唯一的确定一个二叉树;