1 一般的二叉树

二叉树指的是每个节点都拥有两个子树的有序树,左边的称为左子树,右边的称为右子树。

二叉树的性质:

  • 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  • 若她的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  • 具有递归性,排序二叉树的左子树、右子树也是排序二叉树。 

正常情况下查找:

 

 

这种情况下,二分查找的话,时间复杂度相对较低。

如果是当插入的一组元素恰好为有序时:

 

 

此时二叉树就退化成了链表。查找时只有一个个遍历,时间复杂度最高

正是这种情况的存在,才有了平衡二叉树。

2 平衡二叉树

 

左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。

平衡二叉树满足两个条件:

  • 平衡二叉树必须是排序二叉树,也就是说平衡二叉树他的左子树所有节点的值必须小于根节点的值,它的右子树上所有节点的值必须大于它的根节点的值。
  • 左子树和右子树的深度之差的绝对值不超过1。

   这样看起来,平衡二叉树本质就是带了平衡功能的排序二叉树,但是,平衡二叉树插入或删除节点时,由于子树的深度差查过了1,平衡二叉树的平衡状态就被破坏,它就不再是一颗平衡二叉树,为了让他重新维持在一个平衡状态,就需要对其进行旋转处理。

显然,如果在【插入/删除】很频繁的场景中,平衡树需要频繁调整,这会使平衡树的性能大打折扣,为了解决这个问题,于是有了红黑树。

3 红黑树

 

红黑树具有如下特点:

  • 每个节点非黑即红。
  • 根节点总是黑色的。
  • 每个叶子节点(NIL)都是黑色的。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点]
  • 如果节点是红色的,则它的子节点必须是黑色的(反之不一定)。
  • 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑色节点。(这里指到叶子节点的路径)

拉链法导致的链表过深问题为什么不用二叉查找树代替,而选择红黑树?为什么不一直使用红黑树?

     之所以选择红黑树是为了解决二叉查找树的缺陷,二叉查找树在特殊情况下会变成一条线性结构(这就跟原来使用链表结构一样了,造成很深的问题),遍历查找会非常慢。而红黑树在插入新数据后可能需要通过左旋,右旋、变色这些操作来保持平衡,引入红黑树就是为了查找数据快,解决链表查询深度的问题,红黑树属于平衡二叉树,但是为了保持“平衡”是需要付出代价的,但是该代价所损耗的资源要比遍历线性链表要少,所以当长度大于 8 的时候,会使用红黑树,如果链表长度很短的话,根本不需要引入红黑树,引入反而会慢。

此外,还有Mysql索引里的B树,我们另外总结。

 

 

 

 

 

posted on 2022-12-09 09:41  xue123  阅读(135)  评论(0编辑  收藏  举报