public class algorithm {
public static void main(String[] args) {
avlTree t=new avlTree(new int[]{1,2,3,4,5});
t.toBeBalance();
t.midOrder(t.root);
// avlTree t=new avlTree(new int[]{5,4,2,3,1,7,9,7,6});
// avlTree t=new avlTree(new int[]{5,4,7,9,7,6});
// t.preOrder(t.root);
// System.out.println();
// t.rightRotate(t.root,t.rootPapa);
// t.preOrder(t.root);
// System.out.println();
// t.leftRotate(t.root,t.rootPapa);
// t.preOrder(t.root);
// System.out.println();
// t.leftRotate(t.root,t.rootPapa);
// t.preOrder(t.root);
// System.out.println();
// t.preOrder(t.root);
// t.delNode(t.rootPapa,t.root,5);
// t.delNode(t.rootPapa,t.root,6);
// t.addNode(6);
// avlNode node=new avlNode(5,null,null);
// t.addNode(t.root,node);
// t.midOrder(t.root);
// System.out.println();
// if(t.balance())
// System.out.println("平衡树");
}
}
class avlTree{
avlNode root=null;
avlNode rootPapa=new avlNode(0,null,null);
public avlTree(int []arr)
{
if(arr==null) {
System.out.println("传入数组为空,无法构建AVL树");
return;
}
root=new avlNode(arr[0],null,null);
rootPapa.setLeft(root);
rootPapa.setRight(root);
for(int i=1;ivalue)
{
if(r.getLeft()==null)
{
avlNode left=new avlNode(value,null,null);
r.setLeft(left);
return;
}
else
{
r=r.getLeft();
}
}
else
{
if(r.getRight()==null)
{
avlNode right=new avlNode(value,null,null);
r.setRight(right);
return;
}
else
{
r=r.getRight();
}
}
}
}
public void addNode(avlNode root,avlNode node)
{
avlNode r=root;
while(r!=null)
{
if(r.getValue()>node.getValue())
{
if(r.getLeft()==null)
{
r.setLeft(node);
return;
}
else
{
r=r.getLeft();
}
}
else
{
if(r.getRight()==null)
{
r.setRight(node);
return;
}
else
{
r=r.getRight();
}
}
}
}
public void midOrder(avlNode root)
{
if(root!=null)
{
midOrder(root.getLeft());
System.out.print(root.getValue()+" ,"+"("+getDepth(root)+") ,");
midOrder(root.getRight());
}
}
public void preOrder(avlNode root)
{
if(root!=null)
{
System.out.print(root.getValue()+" ,");
preOrder(root.getLeft());
preOrder(root.getRight());
}
}
public void posOrder(avlNode root)
{
if(root!=null)
{
posOrder(root.getLeft());
posOrder(root.getRight());
System.out.print(root.getValue()+" ,");
}
}
public int getDepth(avlNode root)
{
if(root==null)
return 0;
int dl=getDepth(root.getLeft());
int dr=getDepth(root.getRight());
return dl>dr?dl+1:dr+1;
}
public void delNode(avlNode papa,avlNode root,int value)
{
if(root!=null) {
if (root.getValue() == value) {
if(papa.getLeft().getValue()==root.getValue())
{
if(root.getLeft()==null&&root.getRight()==null)
papa.setLeft(null);
else if(root.getLeft()!=null&&root.getRight()!=null)
{
avlNode RIGHT=root.getRight();
papa.setLeft(root.getLeft());
addNode(root.getLeft(),RIGHT);
}
else if(root.getLeft()!=null){
papa.setLeft(root.getLeft());
}
else {
papa.setLeft(root.getRight());
}
}
else {
if(root.getLeft()==null&&root.getRight()==null)
papa.setRight(null);
else if(root.getLeft()!=null&&root.getRight()!=null)
{
avlNode RIGHT=root.getRight();
papa.setRight(root.getLeft());
addNode(root.getRight(),RIGHT);
}
else if(root.getLeft()!=null){
papa.setRight(root.getLeft());
}
else {
papa.setRight(root.getRight());
}
}
} else {
delNode(root, root.getLeft(), value);
delNode(root, root.getRight(), value);
}
}
this.root=this.rootPapa.getLeft();
}
public boolean balance()
{
return !(getDepth(this.root.getLeft())-getDepth(this.root.getRight())>1||getDepth(this.root.getLeft())-getDepth(this.root.getRight())<-1);
}
public void rightRotate(avlNode root,avlNode rootPapa)
{
if(root==null||rootPapa==null)
return;
if(root.getLeft()==null)
return;
if(rootPapa.getRight().getValue()==root.getValue())
{
rootPapa.setRight(root.getLeft());
root.setLeft(root.getLeft().getRight());
rootPapa.getRight().setRight(root);
}
else
{
rootPapa.setLeft(root.getLeft());
root.setLeft(root.getLeft().getRight());
rootPapa.getLeft().setRight(root);
}
if(this.rootPapa.getLeft()!=this.rootPapa.getRight())
{
if(this.rootPapa.getLeft()!=null&&(this.rootPapa.getLeft().getLeft()==this.rootPapa.getRight()||this.rootPapa.getLeft().getRight()==this.rootPapa.getRight()))
{
this.rootPapa.setRight(this.rootPapa.getLeft());
}
else
{
this.rootPapa.setLeft(this.rootPapa.getRight());
}
this.root=this.rootPapa.getLeft();
}
}
public void leftRotate(avlNode root,avlNode rootPapa)
{
if(root==null||rootPapa==null)
return;
if(root.getRight()==null)
return;
if(rootPapa.getRight().getValue()==root.getValue())
{
rootPapa.setRight(root.getRight());
root.setRight(root.getRight().getLeft());
rootPapa.getRight().setLeft(root);
}
else
{
rootPapa.setLeft(root.getRight());
root.setRight(root.getRight().getLeft());
rootPapa.getLeft().setLeft(root);
}
if(this.rootPapa.getLeft()!=this.rootPapa.getRight())
{
if(this.rootPapa.getLeft()!=null&&(this.rootPapa.getLeft().getLeft()==this.rootPapa.getRight()||this.rootPapa.getLeft().getRight()==this.rootPapa.getRight()))
{
this.rootPapa.setRight(this.rootPapa.getLeft());
}
else
{
this.rootPapa.setLeft(this.rootPapa.getRight());
}
this.root=this.rootPapa.getLeft();
}
}
public void beBalance(avlNode root,avlNode rootPapa)
{
if(root==null||rootPapa==null)
{
System.out.println("空树无法建立平衡树");
return;
}
if(getDepth(root.getLeft())-getDepth(root.getRight())>1)
{
while(getDepth(root.getLeft().getRight())>getDepth(root.getLeft().getLeft()))
{
leftRotate(root.getLeft(),root);
}
rightRotate(root,rootPapa);
}
else if(getDepth(root.getLeft())-getDepth(root.getRight())<-1)
{
while(getDepth(root.getRight().getLeft())>getDepth(root.getRight().getRight()))
{
rightRotate(root.getRight(),root);
}
leftRotate(root,rootPapa);
}
}
public void toBeBalance()
{
while(!balance())
{
beBalance(root,rootPapa);
}
}
}
class avlNode{
private int value;
private avlNode left;
private avlNode right;
public avlNode(int value,avlNode left,avlNode right)
{
this.value=value;
this.left=left;
this.right=right;
}
public void setLeft(avlNode left)
{
this.left=left;
}
public void setRight(avlNode right)
{
this.right=right;
}
public void setValue(int value)
{
this.value=value;
}
public int getValue()
{
return this.value;
}
public avlNode getLeft()
{
return this.left;
}
public avlNode getRight()
{
return this.right;
}
}
代码段中的avlNode类和bstNode一样,就是节点中的数据集合和基于这些数据的操作,avlTree是基于avlNode的avl树的数据结构
root表示当前树的根节点,rootPapa表示指向root的节点,因为像删除操作,平衡二叉树操作如果影响到root很容易导致root被java回收机制回收掉,所以需要保证有个节点指向,也方便这些操作的进行