avl的实现代码-摘自数据结构实现java版本(个人笔记整理)

来源:互联网 发布:vb考试系统 编辑:程序博客网 时间:2024/05/16 13:05

avl树的调整

package search;



import tree.BinTreeNode;


public class AVLTree {
//判断是否平衡
public boolean isBanlance(BinTreeNode node){
if(node==null) return true;
int h1 = (node.hasLChild())? node.getlChild().getHeight():-1;
int h2 = (node.hasRightChild())? node.getrChild().getHeight():-1;
return Math.abs(h1-h2)<=1;

}
//返回最高子树
public BinTreeNode higherSubT(BinTreeNode node){
int h1= (node.hasLChild())?node.getlChild().getHeight():-1;
int h2 =(node.hasRightChild())?node.getrChild().getHeight():-1;
if(h1>h2) return node.getlChild();
if(h1<h2) return node.getrChild();
//如果相等的话就看看是左子树还是右子树
else if(node.isLeftChild()) return node.getlChild();
else if(node.isRightChild()) return node.getrChild();
return null;
}
//平衡节点的调整,左旋和右旋转的四种情况可以归结为t1,t2,t3,t4四个子树和a,b,c的断开和重新连接
public BinTreeNode rotate(BinTreeNode z){
//失衡节点
BinTreeNode y = higherSubT(z);
BinTreeNode x = higherSubT(y);
BinTreeNode parent = z.getParent();
boolean isLeft =z.isLeftChild();
//四颗子树
BinTreeNode t0,t1,t2,t3;
//三个节点
BinTreeNode a,b,c;
//四中命名方式
if(y.isLeftChild()){
c =z;
t3 = z.getrChild();
if(x.isLeftChild()){
b = y;
a = x;
t0 = a.getlChild();
t1 = a.getrChild();
t2 = b.getrChild();
}else{
a = y;
b = x;
t0 = a.getlChild();
t1 = b.getlChild();
t2 = b.getrChild();
}

}else{
a =z;
t0 = a.getlChild();
if(x.isRightChild()){
b = y;
c = x;
t1= b.getlChild();
t2 = c.getlChild();
t3 = c.getrChild();
}else{
c = y ;
b = x;
t1 = b.getlChild();
t2 = b.getrChild();
t3 = b.getrChild();
}
}
//摘下节点
x.sever();
y.sever();
z.sever();
if(t0!=null)
t0.sever();
if(t1!=null)
t1.sever();
if(t2!=null)
t2.sever();
if(t3!=null)
t3.sever();
//重新连接
b.setlChild(a);
b.setrChild(c);
a.setlChild(t0);
a.setrChild(t1);
b.setlChild(t2);
b.setrChild(t3);
if(parent!=null){
if(isLeft) parent.setlChild(b);
else parent.setrChild(b);
}
return b;
}
  //重新平衡二叉树
public BinTreeNode reBanlance(BinTreeNode node){
BinTreeNode v = node;
while(node!=null){
if(!isBanlance(node)) rotate(node);
v = node;
//向上传递继续平衡
node = node.getParent();
}
return v;
}

}

//二叉树的查找

package search;


import tree.BinTreeNode;


public class TreeSearch {
//查找
public BinTreeNode binTsearch(Object ele){
return null;
}
//最大值,最右节点
public BinTreeNode max(BinTreeNode node){
BinTreeNode p= node;
if(p!=null)
while(p.hasRightChild()){
p = p.getrChild();
}
return p;
}
//最小值,最左节点
public BinTreeNode min(BinTreeNode node){
BinTreeNode p =node;
if(p!=null)
while(p.hasLChild())p = p.getlChild();
return p;
}
//中序遍历中的后续节点,如果有右子树,右子树的最左节点,没有右子树,如果是有子树则是祖父节点,左子树则是右节点
public BinTreeNode getSuccessor(BinTreeNode node){
if(node==null) return null;
if(node.hasRightChild())return min(node.getrChild());
while(node.isRightChild())node=node.getParent();
return node.getParent();
}
//中序遍历的的前继节点
public BinTreeNode getPredecessor(BinTreeNode node){
if(node==null)return null;
if(node.hasLChild()) return max(node.getlChild());
while(node.isRightChild())node = node.getParent();
return node.getParent();
}
//插入算法,二分查找插入
public void insertNode(Object data,BinTreeNode root){
BinTreeNode current = root;
BinTreeNode  p=null;
while(current!=null){
p = current;
//根据大小关系向左或者向右
}
if(p==null)root = new BinTreeNode(data);
//根据大小设置左右子树
}
//删除算法。确定删除的节点
public BinTreeNode remove(Object ele){
BinTreeNode del = null;
BinTreeNode sub = null;
BinTreeNode v = binTsearch(ele);
if(del==null) return null;
//只有右子树或者只有左子树
if(!del.hasLChild()||!del.hasRightChild()){
del = v;
}else{
//如果有两个子树
del = getPredecessor(v);
v.setData(del.getData());
}
//待删除节点只有左子树或者右子树
if(del.hasRightChild())sub = del.getlChild();
else sub = del.getlChild();

//如果是根节点 root = sub;
//如果是非叶子节点 
if(sub!=null){
if(del.isLeftChild())del.getParent().setlChild(sub);
else del.getParent().setrChild(sub);
}else{
del.sever();
}
return del;
}


}

//个人学习记录,仅供学习参考,如果想进一步实现,还要自己编写和调试

0 0