1.01 AVL树
名字缘由:G.M.Adelson-Velsky和E.M.Landis 。是一种最早的自平衡二分搜索树结构 。
AVL树既是平衡二叉树。AVL树的定义首先要求该树是二叉查找树(满足排序规则),并在此基础上增加了每个节点的平衡因子的定义,一个节点的平衡因子是该节点的左子树树高减去右子树树高的值。
平衡因子BF:该节点的左子树的深度减去它的右子树深度。(平衡二叉树上的所有节点的平衡因子可能是-1,0,1)
1.02 AVLTree代码实现
import java.util.ArrayList;
public class AVLTree<K extends Compareble<K>,V>implements Map<K,V>{
private class Node{ //定义结点
public K key;
public V value;
Node left,right;
public int height; //new 新增高度属性
public Node(K key,V value){ //构造函数
this.key=key;
this.value=value;
left=null;
right=null;
height=1; //new 结点默认高度为1
}
public String toString(){ //组成字符串
return "("+key+","+value+")";
}
}
private Node root;
private int size;
public AVLTree(){ //构造函数
root=null;
size=0;
}
public int getSize(){ //获取AVLTree的元素个数
return size;
}
private boolean isEmpty(){
return size==0;
}
//new 获得结点node的高度
private int getHeight(Node node){
if(node==null){
return 0;
}
return node.height;
}
//new 获得结点node的平衡因子
private int getBalanceFactor(Node node){
if(node==null){
return 0;
}
return node.height;
}
//new 判断二叉树是否是一颗二叉搜索树(中序遍历)
public boolean isBST(){
ArrayList<K> keys=new ArrayList<K>();
inOrder(root,keys);
for(int i=1;i<keys.size();i++){
if(keys.get(i-1).compareTo(keys.get(i))>0){
return false;
}
}
return true;
}
//new 中序遍历
private void inOrder(AVLTree<K,V>.Node node,ArrayList<K> keys){
if(node==null){
return;
}
inOrder(node.left,keys);
keys.add(node.key);
inOrder(node.right,keys);
}
//new 判断该二叉树是否是一颗平衡二叉树(平衡因子的绝对值<=1)
public boolean isBalanced(){
return isBalanced(root);
}
//new 判断以Node为根的二叉树是否是一颗二叉树,递归算法
private boolean isBalanced(Node node){
if(node==null){
return true;
}
int balanceFactor=getBalanceFactor(node);
if(Math.abs(balanceFactor)>1){
return false;
}
return isBalanced(node.left)&&isBalanced(node.right);
}
//new 右旋转操作
private Node rightRotate(node y){
Node x=y.next;
Node T3=x.right;
x.right=y;
y.left=T3;
//更新height结点值
y.heigth=Math.max(getHeight(y.left),getHeight(y.right))+1;
x.height=Math.max(getHeight(x.left),getHeight(x.right))+1;
return x;
}
//new 左旋转操作
private Node leftRotate(Node y){
Node x=y.right;
Node T3=x.left;
x.left=y;
y.right=T3;
//更新height结点值
y.height=Math.max(getHeight(y.left),getHeight(y.right))+1;
x.height=Math.max(getHeight(x.left),getHeight(x.right))+1;
return x;
}
//增加元素
public void add(K key,V value){
root=add(root,key,value);
}
private Node add(Node node,K key,V value){
if(node==null){
size++;
return new Node(key,value);
}
if(key.compareTo(node.key)<0{
node.left=add(node.left,key,value);
}else if(key.compareTo(node.key)>0){
node.right=add(node.right,key,value);
}else{
node.value=value;
}
//new 更新height
node.height=1+Math.max(getHeight(node.left),getHeight(node.right));
//new计算平衡因子
int balanceFactor=getBalanceFactor(node);
if(Math.abs(balanceFactor)>1){
System.out.println("unbalanced:"+balanceFactor);
}
//new 平衡维护
//new 1.左侧的左侧不平衡-》LL
if(balanceFactor>1&&getBalanceFactor(node.left)>=0){
return rightRotate(node);
}
//new 2.右侧的右侧不平衡-》RR
if(balanceFactor<-1&&getBalanceFactor(node.right)<=0){
return leftRotate(node);
}
//new 3.左侧的右侧不平衡-》LR
if(balanceFactor>1&&getBalanceFactor(node.left)<0){
node.left=leftRotate(node.left);
return rightRotate(node);
}
//new 4.右侧的左侧不平衡-》RL
if(balanceFactor<-1&&getBalanceFactor(node.right)>0){
node.right=rightRotate(node.right);
return leftRotate(node);
}
return node;
}
public V get(K key){ //根据键找值
Node node=getNode(root,key);
return node==null?null:node.value;
}
public void set(K key,V value){ //修改元素
Node node=getNode(root,key);
if(node==null){
throw new IllegalArgumentException("doesn't exist!");
}
node.value=value;
}
public V remove(K key){ //删除元素
Node node=getNode(root,key);
if(node!=null){
root=remove(root,key);
return node.value;
}
return null;
}
private Node remove(Node node,K key){
if(node==null){
return null;
}
//只需要将删除结点后的新树的根进行自平衡即可
//new 用retNode接收返回的结点
Node retNode;
if(key.compareTo(node.key)<0){
node.left=remove(node.left,key);
retNode=node;
}else if(key.compareTo(node.key)>0){
node.right=remove(node.right,key);
retNode=node;
}else{
if(node.left==null){
Node rightNode=node.left;
node.right=null;
size--;
retNode=rightNode;
}else if(node.right==null){
Node leftNode=node.left;
node.left=null;
size--;
retNode=leftNode;
}else{
Node successor=minimun(node.right);
//new注意Bug所在 removeMin没有自平衡手段
//可以在removeMin中自平衡
//或者在此调用remove即可,只不过要注意左为空,右为空,左右不为空三者是互斥逻辑
//而且甚至会出现为空的情况 注意空指针异常
successor.left=node.left;
node.left=node.right=null;
retNode=successor;
}
}
//new避免空指针
if(retNode==null){
return null;
}
//new更新height
retNode.height=1+Math.amx(getHeight(retNode.left),getHeight(retNode.right));
//new计算平衡因子
int balanceFactor=getBalanceFactor(node);
if(Math.abs(balanceFactor)>1){
System.out.println("unbalanced:"+balanceFactor);
}
//new 平衡维护
//new 1.左侧的左侧不平衡-》LL
if(balanceFactor>1&&getBalanceFactor(node.left)>=0){
return rightRotate(node);
}
//new 2.右侧的右侧不平衡-》RR
if(balanceFactor<-1&&getBalanceFactor(node.right)<=0){
return leftRotate(node);
}
//new 3.左侧的右侧不平衡-》LR
if(balanceFactor>1&&getBalanceFactor(node.left)<0){
node.left=leftRotate(node.left);
return rightRotate(node);
}
//new 4.右侧的左侧不平衡-》RL
if(balanceFactor<-1&&getBalanceFactor(node.right)>0){
node.right=rightRotate(node.right);
return leftRotate(node);
}
return retNode;
}
private Node minimum(Node node){ //获取最小元素
if(node.left==null){
return node;
}else{
return minimum(node.left);
}
}
public boolean contains(K key){ //是否包含
returngetNode(root,key)!=null;
}
private Node getNode(Node node,K key){
if(node==null){
return null;
}
if(key.compareTo(node.key)==0){
return node;
}else if(key.compareTo(node.key)<0){
return getNode(node.left,key);
}else{
return getNode(node.right,key);
}
}
}