一、 二叉树的种类
- 满二叉树
(1)一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。
(2)如果一棵二叉树的结点要么是叶子结点,要么它有两个子结点,这样的树就是满二叉树。
(3)满二叉树的深度为K(从1开始计算),则其结点总数是(2^k) -1 - 完全二叉树
除了底层节点可能没填满,其余每层的节点数都达到最大值,并且底层的节点都集中在该层最左边的若干位置。 - 二叉搜索树(有序树)
(1)若它左子树不为空,则左子树上所有节点的值均小于它的根节点的值。
(2)若它的右子树不空,则右子树上所有节点的值均大小它的根节点的值。
(3)它的左、右子树也分别为二叉搜索树。 - 平衡二叉搜索树(AVL,Adelson-Velsky and Landis)
它是一棵空树,或者左右两边子树的高度差绝对值不超过1,且两个左右子树都是一颗平衡二叉树。
注:C++中map、set、multimap、multiset的底层实现都是平衡二叉搜索树,增删操作的时间复杂度是O(logn)
二、二叉树的遍历方式
- 深度优选遍历(栈stack,先进后出):先往深处遍历,遇到叶子节点再往回遍历
(1)前序遍历:中、左、右
(2)中序遍历:左、中、右
(3)后续遍历:左、右、中 - 广度优先遍历(队列queue,先进先出):一层一层地遍历
(1)层序遍历
三、二叉树的定义
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int val):val(val),left(nullptr),right(nullptr){}
};
四、递归三部曲
- 确定递归函数的参数和返回值
- 确定终止条件
- 确定单层递归的逻辑
五、二叉树题目总结
- 二叉树的构造:前序遍历,先构造中间节点,或者通过递归函数的返回值来添加、删除节点
从中序与后序遍历序列构造二叉树(106)
合并二叉树(617)
在二叉搜索树中插入一个节点(701)
在二叉搜索树中删除一个节点(450)
修剪二叉搜索树(669)
构造一棵平衡二叉搜索树(108) - 求普通二叉树的属性:后序遍历,通过递归函数的返回值做计算
对称二叉树(101)
二叉树的最大深度(104)
二叉树的最小深度(111)
平衡二叉树(110) - 求二叉搜索树的属性:中序遍历,充分利用二叉搜索树的特性
二叉搜索树中寻找节点(700)
验证二叉搜索树(98)
二叉搜索树的最小绝对差(530)
二叉搜索树的众数(501) - 注:对于求普通二叉树的属性,也有个别情况需要使用前序遍历,例如单纯求深度就是用前序遍历;二叉树的所有路径(257)也使用了前序遍历,俄日了方便让父节点指向子节点