二叉树的前中后序遍历(递归)
前序遍历
vector <int> res;
vector<int> main(TreeNode* root){
dfs(root);
return res;
}
void dfs(TreeNode* root){
if (!root) return;
res.push_back(root->val);
dfs(root->left);
dfs(root->right);
}
中序遍历
vector <int> res;
vector<int> main(TreeNode* root){
dfs(root);
return res;
}
void dfs(TreeNode* root){
if (!root) return;
dfs(root->left);
res.push_back(root->val);
dfs(root->right);
}
后序遍历
vector <int> res;
vector<int> main(TreeNode* root){
dfs(root);
return res;
}
void dfs(TreeNode* root){
if (!root) return;
dfs(root->left);
dfs(root->right);
res.push_back(root->val);
}
二叉树的前中后序遍历(迭代)
前序遍历
- 思路:二叉树的迭代遍历一般用栈来存储
栈是先进后出的顺序,如果是前序遍历,输出为中->左->右,所以先将右儿子入栈,再将左儿子入栈
- 模板解法:
- 初始化栈
- 当前节点赋值为根节点
- 将根节点和所有左孩子入栈并加入答案直至当前节点为空
- 每弹出一个栈顶元素就到达当前节点的右孩子
- 代码模板
stack<TreeNode*> stk
vector<int> res
auto cur = root
while (cur || stk.size()){
while (cur){
res.push_back(cur->val)
stk.push(cur)
cur = cur->left
}
auto tmp = stk.top()
stk.pop()
cur = tmp->right
}
- 常规解法:
- 初始化栈
- 将根节点入栈
- 当栈不为空将栈顶元素记录弹出加入答案
- 如果元素有右儿子则将右儿子入栈,如果有左儿子则将左儿子入栈
- 代码模板
stack<TreeNode*> stk;
vector<int> res;
if (root) stk.push(root);
while (stk.size()){
auto c = stk.top();
stk.pop();
res.push_back(c->val);
if (c->right) stk.push(c->right);
if (c->left) stk.push(c->left);
}
中序遍历
- 思路:与前序遍历的模板解法相似,区别是前序遍历中在找树的左底部的过程中记录答案,而中序遍历是找到左底部再开始记录答案
- 模板解法:
- 初始化栈
- 当前节点赋值为根节点
- 将根节点和所有左孩子入栈直至当前节点为空
- 每弹出一个栈顶元素加入答案并到达当前节点的右孩子
- 代码模板
stack<TreeNode*> stk
vector<int> res
auto cur = root
while (cur || stk.size()){
while (cur){
stk.push(cur)
cur = cur->left
}
auto temp = stk.top()
stk.pop()
res.push_back(temp->val)
cur = temp->right
}
后序遍历
- 思路:与前序遍历的模板解法类似
栈是先进后出的顺序,如果是后序遍历,输出为左->右->中,和前序遍历中->左->右相比,可以在前序遍历的基础上将输入改为中->右->左,再将答案数组反转即为左->右->中
- 模板解法:
- 初始化栈
- 当前节点赋值为根节点
- 将根节点和所有右孩子入栈并加入答案直至当前节点为空
- 每弹出一个栈顶元素就到达当前节点的左孩子
- 反转答案数组
- 代码模板
stack<TreeNode*> stk
vector<int> res
auto cur = root
while (cur || stk.size()){
while (cur){
stk.push(cur)
res.push_back(cur->val)
cur = cur->right
}
auto temp = stk.top()
stk.pop()
cur = temp->left
}
reverse(res.begin(), res.end())
二叉树的层序遍历
- 思路:二叉树的前中后序遍历都是用深度优先搜索的方法(dfs)主要使用栈实现,层序遍历是广度优先搜索主要使用队列实现
- 常规解法:
- 初始化队列
- 将根节点加入队列中
- 当队列不为空时,弹出队头元素,加入到答案中
- 如果左子树非空,左子树加入队列
- 如果右子树非空,右子树加入队列
- 代码模板
queue<TreeNode*> q
vector<int> res
q.push(root)
while (q.size()){
int n = q.size()
for (int i = 0
auto cur = q.front()
q.pop()
res.push_back(cur->val)
if (cur->left) q.push(cur->left)
if (cur->right) q.push(cur->right)
}
}
二叉树有关的题目和二叉树遍历的关系
leetcode.226
- 链接leetcode.cn/problems/in…
- 解题方法:有三种方法解本道题
从上到下遍历树的时候翻转左右节点->前序遍历
遍历到树的叶子节点回溯的时候翻转左右节点->后序遍历
遍历每一层,将每一层的左右节点翻转->层序遍历
- leetcode解题代码
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (!root) return root;
swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (!root) return root;
invertTree(root->left);
invertTree(root->right);
swap(root->left, root->right);
return root;
}
};
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
queue<TreeNode*> q;
if (root) q.push(root);
while (q.size()){
int n = q.size();
for (int i = 0; i < n; i ++){
auto c = q.front();
q.pop();
swap(c->left, c->right);
if (c->left) q.push(c->left);
if (c->right) q.push(c->right);
}
}
return root;
}
};
leetcode.589
class Solution {
public:
vector<int> res;
vector<int> preorder(Node* root) {
if (!root) return res;
res.push_back(root->val);
for (auto c: root->children) preorder(c);
return res;
}
};
class Solution {
public:
vector<int> preorder(Node* root) {
stack<Node*> stk;
vector<int> res;
if (root) stk.push(root);
while (stk.size()){
auto c = stk.top();
stk.pop();
res.push_back(c->val);
for (int i = c->children.size() - 1; i >= 0; i --){
stk.push(c->children[i]);
}
}
return res;
}
};
leetcode.590
class Solution {
public:
vector<int> res;
vector<int> postorder(Node* root) {
if (!root) return res;
for (auto c: root->children) postorder(c);
res.push_back(root->val);
return res;
}
};
class Solution {
public:
vector<int> postorder(Node* root) {
stack<Node*> stk;
vector<int> res;
if (root) stk.push(root);
while (stk.size()){
auto c = stk.top();
stk.pop();
res.push_back(c->val);
for (int i = 0; i < c->children.size(); i ++){
stk.push(c->children[i]);
}
}
reverse(res.begin(), res.end());
return res;
}
};