平衡二叉树:
- 空树是平衡二叉树
- 如果一棵树不为空,并且其中所有的子树都满足各自左子树和右子树的高度差都不超过1.
如何判断是否是平衡二叉树:
头节点是head
进行后序遍历
- head的左子树是否是平衡二叉树,如果不是,直接返回false;
- head左子树最深到哪一层,LH
- head的右子树是否是平衡二叉树,如果不是,直接返回false
- head右子树最深到哪一层,RH
- |LH-RH|>1 返回false
- 返回LH,和RH较大的作为head的深度
搜索二叉树
特征:
- 每棵子树的头节点值都比各自左子树上的所有节点的值要大,也都比各自右子树上的所有节点值要小.
- 搜索二叉树按照中序遍历得到的序列一定是从小到大排列的.
- 红黑树.平衡搜索二叉树(AVL)树,都是搜索二叉树的不同实现
给定头结点head判断是否是搜索二叉树
- 改写二叉树中序遍历
- 遍历到每个节点的值时,如果一直比上一个遍历的节点值要大,则是搜素二叉树.否则不是搜索二叉树
- 为了方便同时得到当前节点,和上一个遍历的节点,采用非递归方式实现中序遍历比较合适.
满二叉树
除了最后一层的节点外无任何子节点,剩下的每一层上的节点都有两个子节点
满二叉树的层数记为L,节点数记为N,则N=2L-1
完全二叉树
完全二叉树是指除了最后一层之外,其他每一层的节点数都是满的,如果最后一层满了就是满二叉树,如果最后一层不满,缺少的节点也全部集中在右边也是一颗完全二叉树.
判断一棵树是否是完全二叉树:
- 采用按层遍历的二叉树的方式,从每层的左边向右边一次遍历所有的节点.
- 如果当前节点有右孩子,但是没有左孩子,直接返回false
- 如果当前节点并不是左右孩子全有,那之后的节点必须为叶节点,否则返回false
- 遍历的过程中如果不返回false,遍历结束返回true
后继节点和前驱节点
中序遍历的后一个节点和前一个节点
定义一种包含指向父节点的二叉树类型.定义如下:
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
struct TreeNode *parent;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
该结构比普通二叉树节点多了指向父节点的指针头节点的父节点为空,给定二叉树中某个节点node,返回后继节点.
普通方法:时间复杂度O(n),空间复杂度为O(n)
- 不断寻找父节点,找到头结点
- 找到头结点,做中序遍历,生成中序遍历序列.
- 在中序遍历序列中,node节点的下一个节点就是后继节点
最优解:
情况1.如果node有右子树,后继节点就是右子树的最左边的节点
情况2.如果node没有右子树,先看node是不是node父节点的左孩子,如果是左孩子,此时node节点父节点就是node的后继节点,如果是右孩子就继续向上需找node的后继节点,假设向上移动到的节点记为s,s的父节点记为p,如果发现s是p的左孩子.那么节点p就是node节点的后继节点,否则一直向上移动.
情况3:如果一直向上移动到空节点都没有找到,说明node没有后继节点,返回空即可