AVL树的左子树与右子树高度差不超过 1 ,因此称之为平衡二叉树。 如下图
平衡因子(BF,Balance Factor)
结点的左子树与右子树的高度(深度)差即为该结点的平衡因子,如果某一结点的平衡因子绝对值大于1则说明此树不是平衡二叉树,如需满足平衡,就需要进行旋转。
旋转:
右旋(LL): 向左子树的左孩子插入新节点导致不平衡, 需要右旋才能平衡
function rightRotate(node){
const newNode = node.left;
node.left = nodeNode.right;
newNode.right = node
return newNode
}
左旋(RR): 向右字树的右孩子插入新节点导致不平衡, 需要左旋才能平衡
function leftRotate(node){
const newNode = node.right;
node.right = nodeNode.left;
newNode.left = node
return newNode
}
除此之外,还有 LR(向左字树的右孩子插入新节点导致不平衡,先左旋再右旋),RL(向右字树的左孩子插入新节点导致不平衡,先右旋再左旋)
function lrRotate(node){
node.left = leftRotate(node.left)
return rightRotate(node)
}
function rlRotate(node){
node.right = rightRotate(node.right)
return leftRotate(node)
}
检查二叉树是否平衡
function checkIsBalance(node){
if(node === null){
return node
}
if(getHeight(node.left)-getHeight(node.right) > 1){
if(getHeight(node.left.left) >= getHeight(node.left.right) ){
node = rightRotate(node)
}else{
node = lrRotate(node)
}
}else if(getHeight(node.left)-getHeight(node.right) < -1){
if(getHeight(node.right.left) >= getHeight(node.right.right) ){
node = leftRotate(node)
}else{
node = rlRotate(node)
}
}
return node
}
向avl树插入子节点
function insertNode(node, newNode){
if(node === null){
node = newNode
return node
}else if(newNode.key < node.key){
if(node.left === null){
node.left = newNode;
return node
}else {
node.left = insertNode(node.left, newNode)
node = checkIsBalance(node)
}
}else if(newNode.key > node.key){
if(node.right === null){
node.right = newNode;
return node
}else {
node.right = insertNode(node.right, newNode)
node = checkIsBalance(node)
}
}
return node
}