前言
大家都玩過球球大作戰的遊戲吧,他的原型是Agar.IO,在這款遊戲了我們扮演一個小球,剛出生的我們除了速度快,視野生存能力都一般,爲了追求某種平衡,通過不斷的吞噬其他小球來讓自己變大,變長,但是我們的速度卻在下降.這個追逐平衡的過程呢,就是我們今天的主題,AVL樹,AVL樹也叫二叉平衡樹,是一種二叉排序樹,其中每一個節點的左子樹和右子樹高度差至多等於1.這樣做的好處是,我們的查找會非常方便,而且也避免了二叉樹變成斜樹而帶來的性能影響.
二叉平衡樹的實現原理
在AVL樹中,每當我們插入一個節點,就檢查是否因爲插入而破壞了樹的平衡,如果破話了平衡,就找出最小不平衡樹(距離插入節點最近的,平衡因子大於1的節點爲根的子樹),在保持AVL樹特性的前提下,進行旋轉操作,來達到平衡.那麼破壞平衡的插入是哪4個呢?
插入節點左子樹的左子樹 LL
插入節點左子樹的右子樹 LR
插入節點右子樹的左子樹 RL
插入節點右子樹的右子樹 RR
那麼對於這四種情況,我們分別要用到這些旋轉操作,比如LL要用
//LL旋轉
public static Node rotateWidthLeftChild(Node tree){
Node root=tree.leftChild;
tree.leftChild=root.rightChild;
root.rightChild=tree;
tree.height=Math.max(height(tree.leftChild), height(tree.rightChild))+1;
root.height=Math.max(height(root.leftChild), tree.height)+1;
return root;
}
LR要用
//LR
public static Node doubleWidthLeftChild(Node tree){
tree.leftChild=rotateWidthRightChild(tree.leftChild);
return rotateWidthLeftChild(tree);
}
RR要用
//RR旋轉
public static Node rotateWidthRightChild(Node tree){
Node root=tree.rightChild;
tree.rightChild=root.leftChild;
root.leftChild=tree;
tree.height=Math.max(height(tree.leftChild), height(tree.rightChild))+1;
root.height=Math.max(height(root.leftChild), tree.height)+1;
return root;
}
RL要用
//RL
public static Node doubleWidthRightChild(Node tree){
tree.rightChild=rotateWidthLeftChild(tree.rightChild);
return rotateWidthRightChild(tree);
}