1. 概述
二叉树遍历就是以一定的次序访问树中每个节点并输出其值,每个节点有且仅被访问一次。
根据
根节点
的访问顺序不同,二叉树的遍历方式可分为:
- 前序遍历:先访问根节点,然后访问左子树,最后访问右子树(
根左右
);- 中序遍历:先访问左子树,然后访问根节点,最后访问右子树(
左根右
);- 后序遍历:先访问左子树,然后访问右子树,最后访问右子树(
左右根
)。另外,二叉树遍历还可以
逐层
从左到右访问所有节点,即层序遍历。
下面分别给出这四种遍历方式的实现代码。
2. 前序遍历
- 方法一:递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
vector<int> res;
public:
vector<int> preorderTraversal(TreeNode* root) {
// 方法一:递归
if (!root) // 如果root为空,直接返回
{
return res;
}
res.push_back(root->val);
preorderTraversal(root->left); // 递归遍历左子树
preorderTraversal(root->right); // 递归遍历右子树
return res;
}
};
- 方法二:迭代
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
// 方法二:迭代
vector<int> res;
if (!root) // 如果root为空,直接返回
{
return res;
}
stack<TreeNode*> stk; // 显式维护一个栈
TreeNode* node = root;
while (!stk.empty() || node)
{
while (node) // 沿着左子树一路向下,直到左子树为空
{
res.push_back(node->val);
stk.push(node); // 入栈
node = node->left;
}
node = stk.top(); // 栈顶元素
stk.pop(); // 弹栈
node = node->right; // 转向node右子树
}
return res;
}
};
3. 中序遍历
- 方法一:递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
vector<int> res;
public:
vector<int> inorderTraversal(TreeNode* root) {
// 方法一:递归
if (!root) // 如果root为空,直接返回
{
return res;
}
inorderTraversal(root->left); // 递归遍历左子树
res.push_back(root->val);
inorderTraversal(root->right); // 递归遍历右子树
return res;
}
};
- 方法二:迭代
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
// 方法二:迭代
vector<int> res;
if (!root) // 如果root为空,直接返回
{
return res;
}
stack<TreeNode*> stk; // 显式维护一个栈
TreeNode* node = root;
while (!stk.empty() || node)
{
while (node) // 沿着左子树一路向下,直至左子树为空
{
stk.push(node); // 入栈
node = node->left;
}
node = stk.top(); // 栈顶元素
stk.pop(); // 弹栈
res.push_back(node->val);
node = node->right; // 转向node右子树
}
return res;
}
};
4. 后序遍历
- 方法一:递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
vector<int> res;
public:
vector<int> postorderTraversal(TreeNode* root) {
// 方法一:递归
if (!root) // 如果root为空,直接返回
{
return res;
}
postorderTraversal(root->left); // 递归遍历左子树
postorderTraversal(root->right); // 递归遍历右子树
res.push_back(root->val);
return res;
}
};
- 方法二:迭代
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
// 方法二:迭代
vector<int> res;
if (!root) // 如果root为空,直接返回
{
return res;
}
stack<TreeNode*> stk; // 显式维护一个栈
TreeNode* node = root;
TreeNode* prev = nullptr; // 记录前一个访问的节点,如果当前该访问某个节点,那前一次访问的一定是该节点的右孩子
while (!stk.empty() || node)
{
while (node) // 沿着左子树一路向下,直到左子树为空
{
stk.push(node);
node = node->left;
}
node = stk.top(); // 栈顶元素
if (!node->right || node->right == prev)
{
res.push_back(node->val);
stk.pop();
prev = node; // 更新prev
node = nullptr;
}
else
{
node = node->right;
}
}
return res;
}
};
5. 层序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if (!root) // 如果root为空,直接返回
{
return res;
}
queue<TreeNode*> q; // 显式维护一个队列
q.push(root); // 根节点入队
while (!q.empty())
{
int sz = q.size(); // 当前队列大小,即当前层节点数目
vector<int> lev; // 存储当前层节点值
for (int i = 0; i < sz; i++) // 对每一层的节点逐一处理
{
TreeNode* node = q.front();
q.pop(); // 出队
lev.push_back(node->val); // 将当前node值加入到lev
if (node->left)
{
q.push(node->left); // 将node左节点入队
}
if (node->right)
{
q.push(node->right); // 将node右节点入队
}
}
res.push_back(lev); // 将当前层结果lev加到res中
}
return res;
}
};