1.二叉树
注:图来自STL源码解析-侯捷
二叉树:每个节点包含一个左子节点,一个右子节点。左右子节点均可能为空。
2.二叉搜索树
定义:任何节点满足:左节点值<本节点值<右子节点值
性质:
- 从根节点一直找其左子节点,找到最后就是二叉搜索树的最小节点。
- 从根节点一直找其右子节点,找到最后就是二叉搜索树的最大节点。
- 插入、访问时间O(log n)
- 最坏情况访问时间为O(n),在若干次操作后二叉搜索树变成单边(全部在左节点或者右节点)
插入操作:
删除操作:
3.平衡二叉树
平衡的定义:没有一个节点深度过大
-
AVL树(Adelson-Velskii-Landis trees)
定义:任何节点的左右子树高度最多差1
节点插入:
插入节点11后,破坏了AVL树的结构(18节点左子树高度为3,右子树高度为1,相差2>AVL树要求1),要调整根节点到插入点路径上深度最深的节点(平衡被破坏的节点) 上图所指的是节点18,因为节点14,12,11(深度比18更大)的平衡没有被破坏,即18是最深的平衡被破坏的节点。根据平衡被破坏可以分为四种情况:
- 插入点在最深的平衡被破坏的节点的左子节点的左子树上,简称左左
- 插入点在最深的平衡被破坏的节点的左子节点的右子树上,简称左右
- 插入点在最深的平衡被破坏的节点的右子节点的左子树上,简称右左
- 插入点在最深的平衡被破坏的节点的右子节点的右子树上,简称右右
例如:上图:节点11位于节点18(平衡被破坏的最深节点)的左子节点14的左子树上,为左左。
左左与右右属于外部插入,可以采用单旋转操作调整AVL树,左右与右左属于内部插入,可以采用双旋转操作调整AVL树
调整方法:
破坏情况 | 应对方法 |
---|---|
左左 | 右旋转 |
右右 | 左旋转 |
左右 | 双旋转(先左后右) |
右左 | 双旋转(先右后左) |
-
单旋转
因为插入了节点11,形成了左左的情况,需要进行单次右旋转,将k2左子树的高度降低,将k2右子树的高度提高(k2是最深平衡被破坏的点)。
可以理解为节点14顶替了节点18的位置,将节点18挤到k2的右子树,再将节点14的右节点16移到节点20的左子节点(因为按照平衡二叉树的原则,它只能成为节点20的左子节点)。- 双旋转
顾名思义,进行两次单旋转,若插入情况为左右、右左,即内侧插入,单旋转无法使其转换成AVL树,需要进行双旋转。
上图即为左右情况,需要进行左旋转、右旋转的双旋转。具体过程如下:
- 双旋转
-
RB-tree(红黑树)
性质:
插入太难了…