目录
平衡:
影响树的平衡的因素主要有,插入顺序,删除节点。一旦树失去了平衡性,其查找效率就会下降,甚至失去查找效率。
分类:
AVL Tree 和 RB Tree (红黑树)
最小不平衡子树 :
左边二叉树的节点45的BF = 1,插入节点43后,节点45的BF = 2。节点45是距离插入点43最近的BF不在[-1,1]范围内的节点,因此以节点45为根的子树为最小不平衡子树。
AVL Tree
一棵AVL树有如下必要条件:
条件一:它必须是二叉查找树。(大小顺序都是搜索树的形式,黄色节点不满足)
条件二:每个节点的左子树和右子树的高度差至多为1。(黄色节点不满足)
AVL树的失衡调整的四种情况
1.左单旋(RR)
注:这里的取名,左单旋右单旋什么的,网上很混乱,所以只需要看懂下面的定义和原理即可,名字可以不管。
当我们在右子树插入右孩子导致AVL失衡时,我们需要进行单左旋调整。旋转围绕最小失衡子树的根节点进行。在删除新节点时也有可能会出现需要单左旋的情况。
如下图:
关键代码:
prchild = proot->_right; //proot指的就是最小不平衡子树的根,上面的节点4就是 proot
proot->_right = prchild->_left;
prchild->_left = proot;
//然后更新节点的高度值
proot->height = max(height(proot->_left),height(proot->_right))+1;
//更新节点的高度值
prchild->height = max(height(prchild->_left), height(prchild->_right)) + 1;
return plchild;
例:
若在下面的平衡搜索二叉树中加入节点15;
利用上面的关键代码,
prchild = proot->_right; //上面的 节点5 就是 proot ,自然而然 prchild 就是 节点10
proot->_right = prchild->_left;
prchild->_left = proot;
补充:
实际上下面这种情况也是符合左旋的,插入节点13,利用左单旋,可以得到右图
2.右单旋(LL)
在左子树上插入左孩子导致AVL树失衡”,我们需要进行单右旋调整。
情况如图所示:
关键代码:
plchild = proot->_left;
proot->_left = plchild->_right;
plchild->_right = proot; //省略部分代码,proot指的就是最小不平衡子树的根
3.右左双旋(RL)
由于第一次旋转后,AVL树仍旧处于不平衡的状态,第二次旋转再次进行调整。
定义:在右子树上插入左孩子导致AVL树失衡",此时我们需要进行先右旋后左旋的调整。
4.左右双旋(LR)
在左子树上插入右孩子导致AVL树失衡,此时我们需要进行先左旋后右旋的调整。
总结
插入方式 | 描述 | 旋转方式 |
LL | 在a的左子树根节点的左子树上插入节点而破坏平衡 | 右旋转 |
RR | 在a的右子树根节点的右子树上插入节点而破坏平衡 | 左旋转 |
LR | 在a的左子树根节点的右子树上插入节点而破坏平衡 | 先左旋后右旋 |
RL | 在a的右子树根节点的左子树上插入节点而破坏平衡 | 先右旋后左旋 |
代码实现理解后补上