树、二叉树、二叉搜索树、AVL树、红黑树
文章目录
树
是一种抽象数据类型(ADT),它是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
- 每个结点有零个或多个子结点;
- 没有父结点的结点称为根结点;
- 每一个非根结点有且只有一个父结点;
- 除了根结点外,每个子结点可以分为多个不相交的子树;
二叉树
每个节点最多有两个字节点
二叉搜索树(二叉排序树)
- 若左子树不为空,则左树上所有节点的值均小于他的根节点值。
- 若右子树不为空,则右树上所有节点的值均大于他的根节点值。
- 它的左右子树也分别为二叉搜索树。
二叉搜索树的查找
从根节点开始查找
- 查找值比当前节点值大,继续查找右子树;
- 查找值比当前节点值小,继续查找左子树;
- 查找值等于当前节点值,查找成功。
例如:上图二叉排序树中查找8:1、大于7,找右子树;2、小于11,找左子树;3、小于9,找左子树,等于8找到。
二叉搜索树的插入
与查找过程类似,从根节点开始
- 插入值比当前节点值大,继续比较右子树;
- 插入值比当前节点值小,继续比较左子树;
- 直到比较节点为空时,进行插入。
例如:上图二叉排序树中插入10:1、大于7,比较右子树;2、小于11,比较左子树;3、大于9,比较右子树;4、右子树为空,进行插入。
二叉搜索树的遍历
- 前序遍历:父节点->左孩子节点->右孩子节点
- 中序遍历:左孩子节点->父节点->右孩子节点
- 后序遍历:左孩子节点->右孩子节点->父节点
例如:上图二叉排序树
前序遍历:7->5->4->3->6->11->9->8->10->12
中序遍历(常用):3->4->5->6->7->8->9->10->11->12
后序遍历:3->4->6->5->8->10->9->12->11->7
二叉搜索树的删除
删除的元素没有子节点:直接删除
删除的元素有一个左子节点,做子节点顶替删除节点位置
删除节点含有右子节点,这就有说到了:由后继节点继承父节点,什么是后继节点呢?后继节点就是比当前节点大的最小节点,这里也就是:
- 如果当前节点的右孩子节点没有左孩子,由右孩子节点继承。如删除图(1)
- 如果当前节点的右孩子节点有左孩子,那就依次找左孩子,由最小的那个继承。如删除图(2)
AVL树
二叉查找树有一个最大的缺点就是极端情况下,构造出的树可能是一个链表,例如{2,3,4,5,6,7,8,9,10}一组数据。构造出来几乎和链表没什么区别,于是AVL树解决了这个问题。
AVL树是最早提出的自平衡二叉树,各叶子节点的左右子树高度想差不超过1,在查找、插入、删除平均和最坏的情况下时间复杂度都是O(logN)。
AVL树不平衡的因素
- 左左型(LL):插入节点在不平衡节点的左侧的左侧
- 右右型(RR):插入节点在不平衡节点的右侧的右侧
- 左右型(LR):插入节点在不平衡节点的左侧的右侧
- 右左型(RL):插入节点在不平衡节点的右侧的左侧
AVL树解决不平衡的方法
(1)左左型(LL)进行右旋转
(2)右右型(RR)进行左旋转
(3)左右型(LR)先进行左旋转变成LL型,在进行右旋转
(4)右左型(RL)先进性右旋转变成RR型,在进行左旋转
注:解决旋转方法参考下面红黑树旋转方法
红黑树
红黑树代码参考点击这里红黑树代码
红黑树的性质
- 每个节点或者是黑色或者是红色
- 根节点是黑色
- 每个叶子节点(NIL)是黑色
- 一个红色节点的子节点必须为黑色
- 从任意一节点到每个叶子节点的路径包含相同数目的黑节点
红黑树解决不平衡的方法
- 变色:节点颜色由红变黑,或者由黑变红
- 左旋转:某旋转节点为该节点,该节点的右孩子节点变成该节点的父节点,右孩子节点的左孩子节点变为该节点的右孩子节点,该节点变为原右孩子节点的左孩子节点
- 右旋转:某旋转节点为该节点,该节点的左孩子节点变成该节点的父节点,左孩子节点的右孩子节点变为该节点的左孩子节点,该节点变为原左孩子节点的右孩子节点
简单理解左旋和右旋:都是找到三个点,左旋:旋转节点,右儿子,右儿子的左孙子;右旋:旋转节点,左儿子,左儿子的右孙子。旋转过程就是自己和儿子互换身份,孙子还是孙子。
红黑树查找
同上述二叉搜索树
红黑树插入
- 找到插入位置,同二叉搜索树
- 插入节点必须为红色
- 维持调节自平衡
插入节点父节点为黑色
直接进行插入
插入节点父节点为红色
1、叔叔节点存在并且为红色
性质4可知,红红不能相连,因此祖父节点肯定为黑色
将父亲和叔叔节点改为黑色,祖父节点改为红色
将祖父节点作为当前节点继续进行处理
2、叔叔节点不存在或者为黑色,并且插入节点的父节点是祖父节点的左子节点
2.1插入节点为左节点(LL双红)
父节点变为黑色,祖父节点变为红色
以祖父节点进行右旋
2.2插入节点为右节点(LR双红)
以父节点左旋,变成(LL双红)再处理
3、叔叔节点不存在或者为黑色,并且插入节点的父节点是祖父节点的右子节点
3.1插入节点为右节点(RR双红)
父节点变黑,祖父节点变红
以祖父节点左旋
3.2插入节点为左节点(RL双红)
以父节点右旋,变成(RR双红)再处理
红黑树的遍历
同上述二叉搜索树
红黑树的删除
替换删除节点的颜色同删除节点颜色一致,删除调整平衡的方法比较复杂。待更新…