第六章 二叉树part01
1.基础
二叉树定义
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
递归:
递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。
2.二叉树的递归遍历
1.递归做题三步骤:
1.确定递归函数的参数和返回值:
递归过程中需要处理的参数放在递归函数
递归是否要返回值,根据该值确定递归函数返回类型
2.确定终止条件:
3.确定单层递归的逻辑:
每一层递归需要处理的信息,还会重复调用自己
2.前后中序遍历
题目:
前https://leetcode.cn/problems/binary-tree-preorder-traversal/
后https://leetcode.cn/problems/binary-tree-postorder-traversal/
中https://leetcode.cn/problems/binary-tree-inorder-traversal/
步骤:
- 确定递归函数的参数和返回值:因为要打印出前序遍历节点的数值,所以参数里需要传入vector来放节点的数值; 除了这一点就不需要再处理什么数据了也不需要有返回值,所以递归函数返回类型就是void,代码如下:
void traversal(TreeNode* cur, vector<int>& vec)
2.确定终止条件:在递归的过程中,如何算是递归结束了呢,当然是当前遍历的节点是空了,那么本层递归就要结束了; 所以如果当前遍历的这个节点是空,就直接return,代码如下:
if (cur == NULL) return;
3.确定单层递归的逻辑:前序遍历是中左右的循序,所以在单层递归的逻辑,是要先取中节点的数值,代码如下:
vec.push_back(cur->val); // 中
traversal(cur->left, vec); // 左
traversal(cur->right, vec); // 右
4.实现
前序遍历:
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
vec.push_back(cur->val); // 中
traversal(cur->left, vec); // 左
traversal(cur->right, vec); // 右
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;//定义数组存放遍历节点的数值
traversal(root, result);//根节点是第一个中间节点
return result;
}
};
后序遍历:
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
traversal(cur->left, vec); // 左
traversal(cur->right, vec); // 右
vec.push_back(cur->val); // 中
}
中序遍历:
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == NULL) return;
traversal(cur->left, vec); // 左
vec.push_back(cur->val); // 中
traversal(cur->right, vec); // 右
}
盲点
1.根节点(root)作为第一个中间节点,它被遍历的顺序决定是遍历方式
前序遍历:中左右, root先被遍历,root的左边,root的右边
后序遍历:左右中 先root左边,root右边,最后是root
中序遍历:左中右 先root左边,root,最后root右边
迭代遍历 (基础不好的录友,迭代法可以放过)
题目链接/文章讲解/视频讲解:https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E8%BF%AD%E4%BB%A3%E9%81%8D%E5%8E%86.html
统一迭代 (基础不好的录友,迭代法可以放过)
这是统一迭代法的写法, 如果学有余力,可以掌握一下