packagecom.binarytree;public class AvlTree>{classNode{
T t;
Node left;
Node right;intheight;publicNode(T t) {this.t=t;
height=1;
left=null;
right=null;
}
}privateNode root;//获取节点高度
public intgetHeight(Node current) {if(current==null) {return 0;
}returncurrent.height;
}//获取节点平衡因子
public intgetBalanceFactor(Node current) {if(current==null) {return 0;
}return getHeight(current.left)-getHeight(current.right);
}//判断是否是平衡二叉树
public booleanisBalanced(Node current) {if(current==null) {return true;
}int balanceFactory=Math.abs(getBalanceFactor(current));if(balanceFactory>1) {return false;
}return isBalanced(current.left)&&isBalanced(current.right);
}//右旋
/*x y
*
* y d ----------> z x
*
* z c a b c d
*
* a b*/
publicNode rightRotate(Node x) {
Node y=x.left;
Node c=y.right;
y.right=x;
x.left=c;//更新树的高度 添加节点的时候每个节点的高度会自动刷新(递归调用),保证下面顺序,先计算子节点高度
x.height=Math.max(getHeight(x.left),getHeight(x.right))+1;
y.height=Math.max(getHeight(y.left),getHeight(y.right))+1;returny;
}//左旋
/** x y
*
* a y -------> x z
*
* d z a d*/
publicNode leftRotate(Node x) {
Node y=x.right;
Node d=y.left;
y.left=x;
x.right=d;//更新高度 新增节点时候、递归每个节点高度会刷新 保证下面顺序,先计算子节点高度
x.height=Math.max(getHeight(x.left),getHeight(x.right))+1;
y.height=Math.max(getHeight(y.left),getHeight(y.right))+1;returny;
}public voidaddNode(T t) {
root=addNode(root,t);
}publicNode addNode(Node current,T t) {if(current==null) {return newNode(t);
}if(t.compareTo(current.t)<0) {
current.left=addNode(current.left,t);
}else if(t.compareTo(current.t)>0) {
current.right=addNode(current.right,t);
}//更新节点高度、递归到的都会更新
current.height=1+Math.max(getHeight(current.left), getHeight(current.right));//平衡因子
int balanceFactor=getBalanceFactor(current);/*LL 右旋操作
*
* x
*
* y
*
* z*/
if(balanceFactor>1&&getBalanceFactor(current.left)>0) {returnrightRotate(current);
}/*RR 左旋操作
* x
*
* y
*
* z*/
if(balanceFactor
}/*LR 先左旋再右旋
* x x z
* 左旋 右旋
* y ----> z -------> y x
*
* z y
*
* x代表current*/
if(balanceFactor>1&&getBalanceFactor(current.left)<0) {
current.left=leftRotate(current.left);returnrightRotate(current);
}/*RL 先右旋再左旋
* x x z
* 右旋 左旋
* y ------> z ----> x y
*
* z y
* x代表crrent*/
if(balanceFactor0) {
current.right=rightRotate(current.right);returnleftRotate(current);
}returncurrent;
}/** 获取当前节点中的最大值,前驱节点*/
publicNode getPreNode(Node node) {
Node tmp=node;if(tmp.right!=null) {
tmp=tmp.right;
}returntmp;
}public voiddeleteNode(T t) {if(t!=null) {
root=deleteNode(root,t);
}
}/** 删除节点
*
**/
publicNode deleteNode(Node node,T t) {
Node curParentNode= null;//主要返回删除节点的替代节点,每次递归时,刷新节点是否处于平衡
if(node==null) {//没找到节点
return null;
}if(t.compareTo(node.t)<0) {
node.left=deleteNode(node.left,t);/** 当值在树中找不到时,返回最后遍历的节点,如下,删除0时候,树中不存在,最后遍历到1返回,递归的时候使其2.left=1
* 2
*
* 1*/curParentNode=node;
}else if(t.compareTo(node.t)>0) {
node.right=deleteNode(node.right,t);
curParentNode=node;//同上
}else{/** (1)删除节点是叶子节点*/
if(node.left==null&&node.right==null) {
curParentNode=null;
}/** (2)删除节点有一个孩子 左孩子或者右孩子*/
if(node.left!=null&&node.right==null) {
curParentNode=node.left;
}else if(node.left==null&&node.right!=null) {
curParentNode=node.right;
}/** (3)删除节点的两个孩子都存在时,找到前驱节点
**/
if(node.left!=null&&node.right!=null) {
Node preNode=getPreNode(node.left);//前驱节点
preNode.left=deleteNode(node.left,preNode.t);//删除前驱节点位置,因为前驱节点要替换到待删除的节点
preNode.right=node.right;
curParentNode=preNode;
}
}if(curParentNode==null)return null;/** 维护平衡
* 更新height*/curParentNode.height= 1+Math.max(getHeight(curParentNode.left),getHeight(curParentNode.right));//平衡因子
int balanceFactor =getBalanceFactor(curParentNode);if(balanceFactor > 1 && getBalanceFactor(curParentNode.left)>=0) {//右旋LL
returnrightRotate(curParentNode);
}if(balanceFactor < -1 && getBalanceFactor(curParentNode.right)<=0) {//左旋RR
returnleftRotate(curParentNode);
}//LR 先左旋再右旋
if(balanceFactor > 1 && getBalanceFactor(curParentNode.left) < 0){
node.left=leftRotate(curParentNode.left);returnrightRotate(curParentNode);
}//RL 先右旋再左旋
if(balanceFactor < -1 && getBalanceFactor(curParentNode.right) > 0){
node.right=rightRotate(curParentNode.right);returnleftRotate(curParentNode);
}returncurParentNode;
}//前序遍历
public voidpreTraversal(Node current) {if(current!=null) {
System.out.println(current.t);
preTraversal(current.left);
preTraversal(current.right);
}
}public static voidmain(String[] args) {
AvlTree avlTree=new AvlTree();
avlTree.addNode(5);
avlTree.addNode(2);
avlTree.addNode(6);
avlTree.addNode(1);
avlTree.addNode(4);
avlTree.addNode(7);
avlTree.addNode(3);
avlTree.deleteNode(7);
avlTree.preTraversal(avlTree.root);
}
}