底层是红黑树(平衡的二叉搜索树)
需要先了解二叉搜索树
二叉搜索树
时间复杂度O(logN)
二叉搜索树要求
- 根节点比左子树中所有结点大,比右子树中所有结点小
- 它的左右子树也满足二叉搜索树
底层实现参考https://www.cnblogs.com/geyouneihan/p/9839205.html
AVL树(平衡树)
当插入数据有序或接近有序时二叉搜索树将退化为单只,查找元素相当于是在顺序表中查找,效率低下。
为了解决这个问题AVL树就出现了。
如果需要一种查询高效且有序的数据结构,而且数据的个数为静态的(即不会改变),可以考虑AVL树,
但一个结构经常修改,就不太适合。
AVL树要求
- 左右子树高度只差(简称平衡因子)的绝对值不超过1(-1/0/1)
- 它的左右子树都是AVL树
红黑树
红黑树要求
- 根节点是黑色
- 如果一个结点是红色,那么他的两个孩子节点是黑色。
- 对于每个结点,从该节点到达后代所有结点的简单路径上黑色结点数目相同
实现:
红黑树的实现中增加一个头结点,因为跟节点必须为黑色,为了与根节点进行区分,将头结点给成黑色,并且让头结点的 pParent 域指向红黑树的根节点,pLeft域指向红黑树中最小的节点,_pRight域指向红黑树中最大的节点,如下:
- 红黑树的插入
检测新节点插入后,红黑树的性质是否造到破坏因为新节点的默认颜色是红色,因此:如果其双亲节点的颜色是黑色,没有违反红黑树任何性质,则不需要调整;但当新插入节点的双亲节点颜色为红色时,就违反了性质三不能有连在一起的红色节点,此时需要对红黑树分情况来讨论:
1.cur插入结点为红,p双亲结点为红,g祖父结点为黑,u叔叔结点存在且为红
解决方案:将p,u改为黑,g改为红,然后把g当成cur,继续向上调整,如下
2. cur为红,p为红,g为黑,u不存在/u为黑
解决方法:p为g的左孩子,cur为p的左孩子,则进行右单旋转,p、g变色–p变黑,g变红;
若:p为g的右孩子,cur为p的右孩子,则进行左单旋转,p、g变色–p变黑,g变红
3.cur为红,p为红,g为黑,u不存在/u为黑
解决方法:p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;
相反,若p为g的右孩子,cur为p的左孩子,则针对p做右单旋转
红黑树与AVL树的比较
红黑树和AVL树都是高效的平衡二叉树,增删改查的时间复杂度都是O( ),红黑树不追求绝对平衡,其只需保证最长路径不超过最短路径的2倍,相对而言,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树实现比较简单,所以实际运用中红黑树更多,map,multimap,set,multiset底层实现都是红黑树。