avl树的java实现代码_AVL树的底层实现(java)

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);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值