文章目录
二叉树遍历
1.前序、中序、后序遍历
1)144. 二叉树的前序遍历
- 递归做法
class Solution {
public:
void preorder(TreeNode* root, vector<int>& res) {
if (root == nullptr) return;
res.push_back(root->val);
preorder(root->left,res);
preorder(root->right, res);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
preorder(root, res);
return res;
}
};
- 迭代做法
用栈实现:只要有做儿子就一直往下遍历,放到栈里;从下往上看走过的点有没有右儿子。
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
while (root || stk.size()) {
while (root) {
res.push_back(root->val);
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
root = root->right;
}
return res;
}
};
2)94. 二叉树的中序遍历
- 递归做法
class Solution {
public:
void inorder(TreeNode* root, vector<int>& res) {
if (root == nullptr) return;
inorder(root->left,res);
res.push_back(root->val);
inorder(root->right, res);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
inorder(root, res);
return res;
}
};
- 迭代做法
前序和中序的差别:前序是先遍历根节点再遍历左子树,中序是先遍历左子树再遍历根节点。
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
while (root || stk.size()) {
while (root) {
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
res.push_back(root->val);
root = root->right;
}
return res;
}
};
3)145. 二叉树的后序遍历
- 递归做法
class Solution {
public:
void postorder(TreeNode* root, vector<int>& res) {
if (root == nullptr) return;
postorder(root->left,res);
postorder(root->right, res);
res.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
postorder(root, res);
return res;
}
};
- 迭代做法
先用前序遍历根 右 左,然后翻转。
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
while (root || stk.size()) {
while (root) {
res.push_back(root->val);
stk.push(root);
root = root->right;
}
root = stk.top();
stk.pop();
root = root->left;
}
reverse(res.begin(), res.end());
return res;
}
};
2.层序遍历
1)102. 二叉树的层序遍历
- 迭代做法
BFS用队列来维护。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if (!root) return res;
queue<TreeNode*> q;
q.push(root);
while (q.size()) {
int currentLevelSize = q.size();
res.push_back(vector<int>());
for (int i = 0; i < currentLevelSize; i++) {
TreeNode* t = q.front();
q.pop();
res.back().push_back(t->val);
if (t->left) q.push(t->left);
if (t->right) q.push(t->right);
}
}
return res;
}
};
- 递归做法
class Solution {
public:
vector<vector<int>> res;
void bfs(TreeNode* root, int level) {
if (!root) return;
if (res.size() <= level) {
vector<int> container;
container.push_back(root->val);
res.push_back(container);
}
else {
res[level].push_back(root->val);
}
if (root->left) bfs(root->left, level + 1);
if (root->right) bfs(root->right, level + 1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
bfs(root, 0);
return res;
}
};
2)103. 二叉树的锯齿形层序遍历
隔层翻转,不需要额外的数据结构辅助。
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> res;
if (!root) return res;
queue<TreeNode*> q;
q.push(root);
int level = 0;
while (q.size()) {
int currentLevelSize = q.size();
res.push_back(vector<int> ());
for (int i = 0; i < currentLevelSize; i++) {
auto t = q.front();
q.pop();
res[level].push_back(t->val);
if (t->left) q.push(t->left);
if (t->right) q.push(t->right);
}
if (level % 2) reverse(res[level].begin(), res[level].end());
level++;
}
return res;
}
};
3)107. 二叉树的层序遍历 II(自下向上的层序遍历)
在102的基础上最后reverse一下。
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> res;
if (!root) return res;
queue<TreeNode*> q;
q.push(root);
while (q.size()) {
int currentLevelSize = q.size();
res.push_back(vector<int>());
for (int i = 0; i < currentLevelSize; i++) {
TreeNode* t = q.front();
q.pop();
res.back().push_back(t->val);
if (t->left) q.push(t->left);
if (t->right) q.push(t->right);
}
}
reverse(res.begin(), res.end());
return res;
}
};
N叉树遍历
1.589. N 叉树的前序遍历
把各个儿子倒序放入栈中。
class Solution {
public:
vector<int> preorder(Node* root) {
vector<int> res;
if(!root) return res;
stack<Node*> stk;
stk.push(root);
while (stk.size()) {
auto t = stk.top();
stk.pop();
res.push_back(t->val);
for (int i = t->children.size() - 1; i >= 0; i--) {
stk.push(t->children[i]);
}
}
return res;
}
};
2.590. N 叉树的后序遍历
前序遍历儿子正向入栈,最后翻转。
class Solution {
public:
vector<int> postorder(Node* root) {
vector<int> res;
if(!root) return res;
stack<Node*> stk;
stk.push(root);
while (stk.size()) {
auto t = stk.top();
stk.pop();
res.push_back(t->val);
for (int i = 0; i < t->children.size(); i++) {
stk.push(t->children[i]);
}
}
reverse(res.begin(), res.end());
return res;
}
};