前情提要:二叉树理论基础
关于二叉树,你该了解这些!| 二叉树理论基础一网打尽,二叉树的种类、二叉树的存储方式、二叉树节点定义、二叉树的遍历顺序_哔哩哔哩_bilibili
1、种类
满二叉树
完全二叉树
二叉搜索树
平衡二叉搜索树:左右两个子树的高度差的绝对值不超过1。
C++中map、set、multimap,multiset的底层实现都是平衡二叉搜索树
2、存储方式
链式存储方式就用指针, 顺序存储的方式就是用数组。
3、遍历方式
4、定义方式
一、递归遍历
每次写递归都要靠直觉? 这次带你学透二叉树的递归遍历!| LeetCode:144.前序遍历,145.后序遍历,94.中序遍历_哔哩哔哩_bilibili
1、递归算法的三个要素:
每次写递归,都按照这三要素来写,可以保证大家写出正确的递归算法!
确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
2、leetcode上三道题目:
二、迭代遍历
(基础不好的录友,迭代法可以放过)
三、统一迭代
(基础不好的录友,迭代法可以放过)
四、层序遍历
讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历_哔哩哔哩_bilibili
1、知识点
层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。
需要借用一个辅助数据结构(即队列)来实现,队列先进先出,符合一层一层遍历的逻辑,而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。
而用栈先进后出适合模拟深度优先遍历,也就是递归的逻辑。
2、代码模版
使用队列实现二叉树广度优先遍历
这份代码也可以作为二叉树层序遍历的模板,打十个就靠它了
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> que;
if (root != NULL) que.push(root);
vector<vector<int>> result;
while (!que.empty()) {
int size = que.size();
vector<int> vec;
// 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
for (int i = 0; i < size; 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);
}
result.push_back(vec);
}
return result;
}
};
# 递归法
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>> result;
int depth = 0;
order(root, result, depth);
return result;
}
};
3、leetcode上十道题目:
学会二叉树的层序遍历,可以一口气打完以下十题: