代码随想录-二叉树
二叉树的理论基础
二叉树的种类
- 满二叉树:如果一棵树只有度为0和度为2的节点,并且度为0的节点在同一层上,则这棵二叉树为满二叉树。
- 完全二叉树:除了最底层节点没被填满,其余每层节点数都达到最大值。
- 二叉搜索树:
- 若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉排序树。
- 平衡二叉树:又被称为AVL树,它具有以下性质:它是一棵空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是都是一棵平衡二叉树
二叉树的存储方式
- 链式存储
- 顺序存储:如果父节点的数组下标为i,那么它的左孩子的数组下标就是i * 2 + 1,右孩子的数组下标就是i * 2 + 2。
二叉树的遍历方式
- 深度优先遍历(递归、迭代)
- 前序遍历
- 中序遍历
- 后序遍历
- 广度优先遍历
- 层次遍历(迭代)
实现方式:栈是递归的一种实现结构。所以前中后序遍历都可以借助栈使用非递归的方式来实现。而广度优先遍历的实现一般借助队列来实现。
二叉树的遍历方式
求二叉树的属性
求二叉树是否对称
可以用递归也可以用迭代。最重要的是结点的放入顺序要弄对。比如迭代法,从前数放一个从后数再放一个。然后比较从队列中取出的两个元素就可以判断是否是对称了。
求二叉树的最大深度、最小深度以及结点个数
都采用层次遍历,求最大深度的话,就直接在循环内部让depth++就可以了;求最小深度的话,在遍历过程中,如果遇到结点的左孩子和右孩子都为空的话,返回depth就可以;求结点个数的话,就在队列弹出元素的时候让结点个数++,返回最后结果就可以。
求二叉树是否平衡
一棵高度平衡的二叉树定义为:一个二叉树每个结点的左右两个子树的高度差的绝对值不超过1。所以求二叉树是否平衡就要求二叉树的高度。求高度的话,这道题就需要采用后序遍历。如果在递归过程中出现左子树的高度与右子树高度之差大于1的话,就返回-1,否则的话就返回1+max(左子树高度,右子树高度)。
求二叉树的所有路径
需要用到递归+回溯。如果碰到结点的左孩子和右孩子都为空,就把得到了path路径加入到结果中。
求二叉树的左叶子之和
递归处理。先求左子树的左叶子之和,再求右子树的左叶子之和,再加上通过根结点判断的左叶子的值,就可得到最终的值。左叶子的判断逻辑为:结点A的左孩子结点B不为空,且结点B的左孩子和右孩子都为空,则结点B为左叶子结点。
求二叉树左下角的值
采用层次遍历处理。遍历到最后一层的时候,取第1个值。
求二叉树的路径总和
- 路径总和:看是否存在一条这样的路径,返回true或false。采用递归处理,递归函数有返回类型。
- 路径总和ii:返回所有符合要求的路径。递归+回溯。递归函数无返回类型。
二叉树的修改与构造
翻转二叉树
用递归处理,模拟前序遍历,交换左右孩子,再继续翻转左子树和右子树。
构造二叉树
- 从中序和后序遍历序列构造二叉树
- 从前序和中序遍历序列构造二叉树
这两个题是一类题,以“从中序和后序遍历序列构造二叉树”为例,题目求解过程为:
1.如果数组大小为0,则返回空结点。
2.如果不为空,取后序数组最后一个元素作为结点元素。
3.找到后序数组最后一个元素在中序数组中的位置,把这个位置作为切割点。
4.切割中序数组,切成中序左数组和中序右数组。
5.切割后序数组,切成后序左数组和后序右数组。
6.递归处理左区间和右区间。
构造最大的二叉树
和上一个构造二叉树做法类似,就是每次取数组中最大的元素作为切割点。
合并两个二叉树
采用递归。递归函数传入两棵树的根节点,递归终止的条件就是如果t1为空,就返回t2,如果t2为空,就返回t1。单层处理逻辑就是把t1和t2的值加起来。然后分别合并左子树和右子树。
求二叉搜索树的属性
二叉搜索树中的搜索
可通过递归求解。如果当前结点的值小于要寻找的值,就从根节点的右子树中去寻找;如果当前结点的值大于要寻找的值,就从根结点的左子树中去寻找。
判断一棵树是不是二叉搜索树
如果用中序遍历二叉搜索树的话,得到的是一个有序数组。所以可以通过中序遍历和比较前一个数值是否小于当前数值来判断其是否是一棵二叉搜索树。
求二叉搜索树的最小绝对差
采用中序遍历,求相邻值的绝对差的最小值。
求二叉搜索树的众数
采用中序遍历来统计众数。
将二叉搜索树转成累加树
从树中可看出累加的顺序是右中左,用右中左的顺序进行遍历进行累加。
二叉树公共祖先问题
二叉树的公共祖先问题
自底向上查,采用后序遍历。终止条件:如果root为null或者root为p或root为q,则返回root。然后再返回分别从左子树和右子树中寻找的结果,进而通过判断两个结果是否为空来返回对应的值。
二叉搜索树的公共祖先问题
采用迭代法,如果root.val在p.val和q.val之间,那么root就是p和q的最近公共祖先。
二叉搜索树的修改与构造
二叉搜索树的插入操作。
采用递归法。用root.left或者root.right将返回值接住。
二叉搜索树中的删除操作
采用递归法。要删除的结点有3种情况:左孩子为空;右孩子为空;左右孩子都不为空。左孩子为空,则返回其右孩子;右孩子为空,则返回其左孩子;左右孩子都不为空,把左孩子移到以右孩子为根结点的子树的最左叶子结点的下面。
修剪二叉搜索树
采用递归方法。
将有序数组转换为高度平衡的二叉搜索树
采用递归的方法。从数组最中间的数进行分割,然后递归构造左子树和右子树。