二叉树(BST)
二叉树中,将比父结点大的数放在右结点,比父结点小的数放在左结点,查找时只需要将其跟父结点对比,大则进入右边,小则进入左边,依次往下;
但是数据本身是有序的,就导致查询跟链表一样,查询深度太深,效率低下,所以后面引出了平衡二叉树,降低层次。
平衡树(AVL)
对二叉树的改进,插入删除的时候,保证每个结点对应的左子树和右子树的高度(结点深度)差小于等于1;
拿百度百科的图片当例子
a中,5的平衡因子 = 左子树深度3 - 右子树的深度2 = 平衡因子1,结果为平衡;
b中,3的平衡因子 = 左子树深度2 - 右子树的深度4 = 平衡因子-2,结果为不平衡;
如果超过了就对结构平衡改造(旋转结点),以此来达到树平衡,这样我们在查找的时候就可以按照二分查找来检索,也不会出现退化成链表的情况;
因为平衡树要求每个结点的左子树和右子树的高度差至多等于1,导致需要频繁通过左旋和右旋来进行调整,使性能大打折扣,于是就有了红黑树。
2-3树
2-3数是一种平衡的多路查找树,跟二叉树规则有点像;
结点可以存放一个或两个元素,结点要么是有3个子结1个两元素的根结,要么是2个子结1个单元素的根结,任意结点到其叶子结点的高度都是相同;
当然,上图是不平衡的,但是这样更直观,上图结点高度不同,最后会融合分裂成一个平衡树;
除了首个数据外,插入数据时会结点融合,使一个结点里有两个元素,如果一个结点存放数据为3个,会分裂成一个根结点两个子结点;
分裂结点后,假设不符合平衡规则,根结点会继续向上融合,如果又不符合平衡规则,又会进行分裂,以此来达到一个树平衡。
2-3数进一步降低了层次,但为了维护平衡性它的编码复杂,但是提升了查询性能。
后面还有2-3-4树,它可以再次降低的树的高度,但是对应的编码会更加复杂,所以大多数会使用红黑树。
红黑树(Red-Black Tree)
除了有二叉平衡树的一些特性,还给结点附加了红黑属性,并且有它的一套规则;
1.结点是红色或黑色。
2.根结点是黑色。
3.每个叶子结点都是黑色的空结点(NIL结点)。
4 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
5.从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。
如果规则被打破就会进行变色或者平衡(旋转),变化规则比较复杂,不深究;
检索效率跟平衡树相差不多,插入和删除操作效率提高很多,因为红黑树对平衡没有AVL平衡树要求那么严格。