LeetCode 144. 二叉树的前序遍历
1、题目
题目链接:144. 二叉树的前序遍历
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[1,2]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
提示:
- 树中节点数目在范围 [0, 100] 内
- -100 <= Node.val <= 100
2、思路
首先我们需要了解什么是二叉树的前序遍历:按照访问根节点——左子树——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。因此整个遍历过程天然具有递归的性质,我们可以直接用递归函数来模拟这一过程。
定义 preorder(root)
表示当前遍历到 root
节点的答案。按照定义,我们只要首先将 root
节点的值加入答案,然后递归调用 preorder(root.left)
来遍历 root
节点的左子树,最后递归调用 preorder(root.right)
来遍历 root
节点的右子树即可,递归终止的条件为碰到空节点。
3、代码
#include <iostream>
#include <vector>
using namespace std;
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:
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;
}
};
4、复杂度分析
- 时间复杂度:O(n),其中 n 是二叉树的节点数。每一个节点恰好被遍历一次。
- 空间复杂度:O(n),为递归过程中栈的开销,平均情况下为 O(logn),最坏情况下树呈现链状,为 O(n)。
LeetCode 94. 二叉树的中序遍历
1、题目
题目链接:94. 二叉树的中序遍历
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
- 树中节点数目在范围 [0, 100] 内
- -100 <= Node.val <= 100
2、思路
首先我们需要了解什么是二叉树的中序遍历:按照访问左子树——根节点——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候我们按照同样的方式遍历,直到遍历完整棵树。因此整个遍历过程天然具有递归的性质,我们可以直接用递归函数来模拟这一过程。
定义 inorder(root)
表示当前遍历到 root
节点的答案,那么按照定义,我们只要递归调用 inorder(root.left)
来遍历 root
节点的左子树,然后将 root
节点的值加入答案,再递归调用 inorder(root.right)
来遍历 root
节点的右子树即可,递归终止的条件为碰到空节点。
3、代码
#include <iostream>
#include <vector>
using namespace std;
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:
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;
}
};
int main() {
Solution s;
TreeNode* root = new TreeNode(1, new TreeNode(2, new TreeNode(3), new TreeNode(4)), new TreeNode(5));
vector<int> res = s.inorderTraversal(root);
for (int i : res) {
cout << i << " ";
}
cout << endl;
return 0;
}
4、复杂度分析
- 时间复杂度:O(n),其中 n 是二叉树的节点数。每一个节点恰好被遍历一次。
- 空间复杂度:O(n),为递归过程中栈的开销,平均情况下为 O(logn),最坏情况下树呈现链状,为 O(n)。
LeetCode 145. 二叉树的后序遍历
1、题目
题目链接:145. 二叉树的后序遍历
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[3,2,1]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
- 树中节点的数目在范围 [0, 100] 内
- -100 <= Node.val <= 100
2、思路
首先我们需要了解什么是二叉树的后序遍历:按照访问左子树——右子树——根节点的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。因此整个遍历过程天然具有递归的性质,我们可以直接用递归函数来模拟这一过程。
定义 postorder(root)
表示当前遍历到 root
节点的答案。按照定义,我们只要递归调用 postorder(root->left)
来遍历 root
节点的左子树,然后递归调用 postorder(root->right)
来遍历 root
节点的右子树,最后将 root
节点的值加入答案即可,递归终止的条件为碰到空节点。
3、代码
#include <iostream>
#include <vector>
using namespace std;
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:
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;
}
};
int main() {
Solution s;
TreeNode* root = new TreeNode(1, new TreeNode(2, new TreeNode(4), new TreeNode(5)), new TreeNode(3, new TreeNode(6), new TreeNode(7)));
vector<int> res = s.postorderTraversal(root);
for (int i : res) {
cout << i << " ";
}
cout << endl;
return 0;
}
4、复杂度分析
- 时间复杂度:O(n),其中 n 是二叉树的节点数。每一个节点恰好被遍历一次。
- 空间复杂度:O(n),为递归过程中栈的开销,平均情况下为 O(logn),最坏情况下树呈现链状,为 O(n)。