二叉树遍历递归写法
- 递归思想
- 前序、中序、后序的定义
前序遍历
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ans;
preorder(root, ans);
return ans;
}
void preorder(TreeNode* root, vector<int>& ans) {
if (!root) return;
ans.emplace_back(root->val); // 中
preorder(root->left, ans); // 左
preorder(root->right, ans); // 右
}
};
中序遍历
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ans;
inorder(root, ans);
return ans;
}
void inorder(TreeNode* root, vector<int>& ans) {
if (!root) return;
inorder(root->left, ans); // 左
ans.emplace_back(root->val); // 中
inorder(root->right, ans); // 右
}
};
后序遍历
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ans;
postorder(root, ans);
return ans;
}
void postorder(TreeNode* root, vector<int>& ans) {
if (!root) return;
postorder(root->left, ans); // 左
postorder(root->right, ans); // 右
ans.emplace_back(root->val); // 中
}
};
二叉树遍历非递归写法
为了统一风格,采用标记法
- DFS
- 栈保存访问顺序
- nullptr标记处理时机
中序遍历(详细注释)
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
// 返回值构造
vector<int> ans;
// 非递归 --> 辅助栈
stack<TreeNode*> stk;
// 非空检查
if (root) stk.push(root);
// 主干代码
while (!stk.empty()) {
// 访问栈顶结点 并弹出
TreeNode* node = stk.top();
stk.pop();
// 如果是实际存在的结点
if (node) {
// 1. 压入相关结点, 由中序遍历, 我们按左中右逆序压栈
if (node->right) stk.push(node->right);
stk.push(node);
// 2. 关键:访问但未处理中结点, 我们压入空指针作为标记
stk.push(nullptr);
if (node->left) stk.push(node->left);
}
// 如果是标记结点, 则意味着我们需要处理结点了
else {
node = stk.top();
stk.pop();
ans.emplace_back(node->val);
}
}
return ans;
}
};
前序遍历(变化点注释)
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ans;
stack<TreeNode*> stk;
if (root) stk.push(root);
while (!stk.empty()) {
TreeNode* node = stk.top();
stk.pop();
if (node) {
// 与中序遍历的差别仅在 访问顺序以及处理标记
// 中左右逆序
if (node->right) stk.push(node->right);
if (node->left) stk.push(node->left);
stk.push(node);
// 标记中点
stk.push(nullptr);
}
else {
node = stk.top();
stk.pop();
ans.emplace_back(node->val);
}
}
return ans;
}
};
后序遍历(变化点注释)
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ans;
stack<TreeNode*> stk;
if (root) stk.push(root);
while (!stk.empty()) {
TreeNode* node = stk.top();
stk.pop();
if (node) {
// 与中序遍历的差别仅在 访问顺序以及处理标记
// 左右中逆序
stk.push(node);
// 标记中点
stk.push(nullptr);
if (node->right) stk.push(node->right);
if (node->left) stk.push(node->left);
}
else {
node = stk.top();
stk.pop();
ans.emplace_back(node->val);
}
}
return ans;
}
};
二叉树层序遍历(详细注释)
- BFS
- 队列保存访问顺序
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
// 返回值构造,原题目输出是二维的
vector<vector<int>> ans;
// BFS --> 辅助队列
queue<TreeNode*> que;
// 非空检查
if (root != nullptr) {
que.push(root);
}
// 主干代码
while (!que.empty()) {
// 1. 确定该层有多少结点
int size = que.size();
// 2. 保存该层处理的结点值
vector<int> level;
for (int i = 0; i < size; ++i) {
// 3. 访问并处理结点
TreeNode* node = que.front();
que.pop();
level.emplace_back(node->val);
// 4. 保存下一层的结点
if (node->left != nullptr) {
que.push(node->left);
}
if (node->right != nullptr) {
que.push(node->right);
}
}
// 5. 保存该层结点处理结果
ans.emplace_back(level);
}
return ans;
}
};
- 上一段代码返回值是按层输出,如果直接输出参考下列代码
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
vector<int> ans;
if (!root) return ans;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()) {
TreeNode* node = que.front();
que.pop();
ans.emplace_back(node->val);
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
return ans;
}
};