二叉树的深度优先遍历
文档讲解:
代码随想录:二叉树的递归遍历
代码随想录:二叉树的迭代遍历
题目
LeetCode144.二叉树的前序遍历
递归遍历:
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == nullptr)
return;
vec.push_back(cur->val);
traversal(cur->left, vec);
traversal(cur->right, vec);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
traversal(root, res);
return res;
}
};
迭代遍历:
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr)
return res;
stack<TreeNode*> stk;
stk.push(root);
while (!stk.empty()) {
TreeNode* cur = stk.top();
stk.pop();
res.push_back(cur->val);
if (cur->right)
stk.push(cur->right);
if (cur->left)
stk.push(cur->left);
}
return res;
}
};
LeetCode145.二叉树的后序遍历
递归遍历:
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == nullptr)
return;
traversal(cur->left, vec);
traversal(cur->right, vec);
vec.push_back(cur->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
traversal(root, res);
return res;
}
};
迭代遍历:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr)
return res;
stack<TreeNode*> stk;
stk.push(root);
while (!stk.empty()) {
TreeNode* cur = stk.top();
stk.pop();
res.push_back(cur->val);
if (cur->left)
stk.push(cur->left);
if (cur->right)
stk.push(cur->right);
}
reverse(res.begin(), res.end());
return res;
}
};
LeetCode94.二叉树的中序遍历
递归遍历:
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == nullptr)
return;
traversal(cur->left, vec);
vec.push_back(cur->val);
traversal(cur->right, vec);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
traversal(root, res);
return res;
}
};
迭代遍历:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
TreeNode* cur = root;
while (cur != nullptr || !stk.empty()) {
if (cur != nullptr) {
stk.push(cur);
cur = cur->left;
} else {
cur = stk.top();
stk.pop();
res.push_back(cur->val);
cur = cur->right;
}
}
return res;
}
};
二叉树的层序遍历
文档讲解:代码随想录:二叉树的层序遍历
题目
LeetCode102.二叉树的层序遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。(即逐层地,从左到右访问所有节点)。
迭代遍历:
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> que;
if (root != nullptr)
que.push(root);
while (!que.empty()) {
vector<int> vec;
int n = que.size();
for (int i = 0; i < n; i++) {
TreeNode* cur = que.front();
que.pop();
vec.push_back(cur->val);
if (cur->left)
que.push(cur->left);
if (cur->right)
que.push(cur->right);
}
res.push_back(vec);
}
return res;
}
};
递归遍历:
class Solution {
public:
void order(TreeNode* cur, vector<vector<int>>& result, int depth) {
if (cur == nullptr)
return;
if (result.size() == depth)
result.push_back(vector<int>());
result[depth].push_back(cur->val);
order(cur->left, result, depth + 1);
order(cur->right, result, depth + 1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
order(root, res, 0);
return res;
}
};
以下题目利用二叉树的层序遍历解决,为方便理解采用迭代法。
1. LeetCode107.二叉树的层序遍历II
给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> que;
if (root != nullptr)
que.push(root);
while (!que.empty()) {
vector<int> vec;
int n = que.size();
for (int i = 0; i < n; i++) {
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
res.push_back(vec);
}
reverse(res.begin(), res.end());
return res;
}
};
2. LeetCode199.二叉树的右视图
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> res;
queue<TreeNode*> que;
if (root != nullptr)
que.push(root);
while (!que.empty()) {
int n = que.size();
for (int i = 0; i < n; i++) {
TreeNode* node = que.front();
que.pop();
if (i == n - 1)
res.push_back(node->val);
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
}
return res;
}
};
3. LeetCode637.二叉树的层平均值
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 1e-5 以内的答案可以被接受。
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
vector<double> res;
queue<TreeNode*> que;
if (root != nullptr)
que.push(root);
while (!que.empty()) {
int n = que.size();
double sum = 0;
for (int i = 0; i < n; i++) {
TreeNode* node = que.front();
que.pop();
sum += node->val;
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
res.push_back(double(sum / n));
}
return res;
}
};
4. LeetCode429.N叉树的层序遍历
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> res;
queue<Node*> que;
if (root != nullptr)
que.push(root);
while (!que.empty()) {
vector<int> vec;
int n = que.size();
for (int i = 0; i < n; i++) {
Node* node = que.front();
que.pop();
vec.push_back(node->val);
for (auto child : node->children) {
if (child)
que.push(child);
}
}
res.push_back(vec);
}
return res;
}
};
5. LeetCode515.在每个树行中找最大值
给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
vector<int> res;
queue<TreeNode*> que;
if (root != nullptr)
que.push(root);
while (!que.empty()) {
int n = que.size();
int tmp = INT_MIN;
for (int i = 0; i < n; i++) {
TreeNode* node = que.front();
que.pop();
tmp = (tmp > node->val) ? tmp : node->val;
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
res.push_back(tmp);
}
return res;
}
};
6. LeetCode116.填充每个节点的下一个右侧节点指针
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
class Solution {
public:
Node* connect(Node* root) {
queue<Node*> que;
if (root != nullptr)
que.push(root);
while (!que.empty()) {
int n = que.size();
Node* node;
Node* nodePre;
for (int i = 0; i < n; i++) {
if (i == 0) {
node = que.front();
que.pop();
nodePre = node;
} else {
node = que.front();
que.pop();
nodePre->next = node;
nodePre = nodePre->next;
}
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
nodePre->next = nullptr;
}
return root;
}
};
7. LeetCode117.填充每个节点的下一个右侧节点指针II
给定一个二叉树:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL 。
初始状态下,所有 next 指针都被设置为 NULL 。
class Solution {
public:
Node* connect(Node* root) {
queue<Node*> que;
if (root != nullptr)
que.push(root);
while (!que.empty()) {
int n = que.size();
Node* node;
Node* nodePre;
for (int i = 0; i < n; i++) {
if (i == 0) {
node = que.front();
que.pop();
nodePre = node;
} else {
node = que.front();
que.pop();
nodePre->next = node;
nodePre = nodePre->next;
}
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
nodePre->next = nullptr;
}
return root;
}
};
8. LeetCode104.二叉树的最大深度
给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
class Solution {
public:
int maxDepth(TreeNode* root) {
int depth = 0;
queue<TreeNode*> que;
if (root == nullptr)
return 0;
else
que.push(root);
while (!que.empty()) {
int n = que.size();
depth++;
for (int i = 0; i < n; i++) {
TreeNode* node = que.front();
que.pop();
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
}
}
return depth;
}
};
9. LeetCode111.二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
class Solution {
public:
int minDepth(TreeNode* root) {
int depth = 0;
queue<TreeNode*> que;
if (root == nullptr)
return 0;
else
que.push(root);
while (!que.empty()) {
int n = que.size();
depth++;
for (int i = 0; i < n; i++) {
TreeNode* node = que.front();
que.pop();
if (node->left)
que.push(node->left);
if (node->right)
que.push(node->right);
if (!node->left && !node->right)
return depth;
}
}
return depth;
}
};