二叉树学习笔记
学习的视频链接
树的基本定义
树是有n(n>=1)个有限结点组成具有层次关系的集合。树的特点:
- 每个结点有0个或多个子结点
比如:A有3个子结点;J有0个子结点 - 没有父结点的结点称为根结点
比如:A没有父结点,所以A为根结点 - 没有子节点的非根节点称为叶子节点
比如:E,F,I,J,K,L,M都为叶子结点 - 每一个非根结点都只有一个父结点
比如:B的父结点是A,K的父结点是G - 每个结点及其后代结点可以看成一棵树,称为这个结点的父结点的子树
比如:B结点及其后代E,F形成一个数,是B的父结点A的子树
树的相关术语
- 结点的度:一个结点含有的子树个数,称为这个结点的度
- 叶子结点:度为0的结点,称为叶结点或终端结点
- 分支结点:度不为0的结点,称为分支结点或终端结点
- 结点的层次:从根结点开始,根结点的层次为1,根的直接后继结点层次为2,以此类推
- 结点的层序编号:从根开始,从上往下,从左往右排成一个线性序列,依次自然数编号
- 树的度:树种所有结点的度的最大值
- 树的深度(高度):树种结点的最大层次
- 森林:m(m>=0)个互不相交的树的集合,即把根结点去掉,他的所有子树组成的集合,就变成森林。给一个森林添加一个统一的根结点,森林就变成树
二叉树的基本定义
参考链接:https://www.cnblogs.com/feichangnice/p/7726270.html
参考链接:https://zhuanlan.zhihu.com/p/106828968
二叉树就是度不超过2的树(即每个结点最多有两个子结点)
斜二叉树
左斜树:所有结点都只有左子树
右斜树:所有结点都只有右子树
满二叉树(Full Tree)
所有结点都有左子树和右子树,且所有叶子结点在同一层
一个深度为n(n>=1)的满二叉树的特点:
- 每层结点个数为2^(n-1)个
- 总的结点数2^(n) - 1
完全二叉树(Complete Binary Tree)
在一棵二叉树中,除了最后一层,都是满的,并且最后一层或者是满的,或者是右边缺少连续若干节点,成为完全二叉树。
满二叉树是完全二叉树。
二叉查找树(Binary Search Tree)
又称为二叉搜索树,排序二叉树,可为空树,或节点满足左子树所有节点<跟节点<右子树所以节点,不存在相等值的节点。它是具有下列性质的二叉树:
若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
左、右子树也分别为二叉搜索树。
二叉搜索树的中序遍历一定是从小到大排序的
在最好的情况下,二叉搜索树的查找效率比较高,是 O(logn),其访问性能近似于二分法;
但最差时候会是 O(n),比如插入的元素是有序的,生成的二叉搜索树就是一个链表,树的一条腿特变长。
平衡二叉树(Balanced Binary Tree)
平衡二叉树的提出就是为了保证树不至于出现二叉查找树的极端一条腿长现象,尽量保证两条腿平衡。因此它的定义如下:
定义:平衡二叉树要么是一棵空树,要么保证左右子树的高度之差不大于 1,并且子树也必须是一棵平衡二叉树,常见的平衡二叉树有AVl树、红黑树等。
平衡二叉树在添加和删除时需要进行复杂的旋转保持整个树的平衡,最终,插入、查找的时间复杂度都是 O(logn),性能已经相当好了。
二叉树Java API实现
结点类结构
Node {
Node left; //左结点
Node right; //右结点
Key key; //键
Value value; //数据
}
添加结点
put(Key key,Value value)
put(Node node,Key key,Value value)
如果当前树为空,则直接把新节点当做根结点返回
如果当前树不为空,则
如果新结点的Key小于当前结点的Key,则继续找当前结点的左子结点
如果新节点的Key大于当前结点的Key,则继续找当前结点的右子结点
如果新节点的Key等于当前结点的Key,则更新当前结点的Value
查找结点
get(Key key)
get(Node node,Key key)
删除结点
remove(Key key)
remove(Node node,Key key)
遍历所有结点
根据访问根结点的先后顺序,分为前,中,后序遍历
前序遍历
先访问根结点,再访问左子树,最后访问右子树
ABDHIEJKCFG
中序遍历
先访问左子树,再访问根结点,最后访问右子树
HDIBJEKAFCG
后序遍历
先访问左子树,再访问右子树,最后访问根结点
HIDJKEBFGCA
层序遍历
从上往下,从左往右,一层一层访问
ABCDEFGHIJK