[置顶] 平衡树 AVL树的JAVA实现
对旋转的图文解释::
图可以参考这个链接,这里仅提供一种思路http://blog.csdn.net/qq_41104612/article/details/79464112
我实现了一次平衡树,对他有的理解:
旋转发生的条件:
①左右子树的高度差为二
旋转有两种::单旋转,双旋转
无论单旋转还是双旋转,都满足先进行与深度较高的子树同名(右子树对右旋转)旋转,如果是双旋转则随后进行异名旋转
单旋转发生在
①插入时::
插入的节点
在不平衡点的左子树的左子树上(左单旋)
在不平衡点的右子树的右子树上(右单旋)
②删除时::
删除左子树的节点导致该点不平衡且其右子树的右子树存在时(右单旋)
删除右子树的节点导致该点不平衡且其左子树的左子树存在时(左单旋)
双旋转::
①插入时::
插入的节点
在不平衡点的左子树的右子树上(左右旋)
在不平衡点的右子树的左子树上(右左旋)
②删除时::
删除左子树的节点导致该点不平衡且其右子树的右子树不存在时(右左单旋)
删除右子树的节点导致该点不平衡且其左子树的左子树不存在时(左右单旋)
模板类创建,如果只想实现对某个类的平衡树,去掉将类声明写成
class AVLNode
并把T换成基本数据类型或继承了Comparable的类,这里不兹论述
package STL; class AVLNode<T extends Comparable<T>> { public T val; public int height; public AVLNode<T> left,right; public AVLNode(T data) { this(null,null,data); } public AVLNode(AVLNode<T> left, AVLNode<T> right, T data) { this(left,right,data,1); } public AVLNode(AVLNode<T> left, AVLNode<T> right, T data, int height) { this.left=left; this.right=right; this.val=data; this.height = height; } }
package STL; import STL.AVLNode; public class AVLTree<T extends Comparable<T>> { private AVLNode<T> root; private int h(AVLNode<T> x) { if(x==null)return 0; else return x.height; } private AVLNode<T> L(AVLNode<T> x) { AVLNode<T> mid=x.left; x.left=mid.right; mid.right=x; x.height=Math.max(h(x.left),h(x.right))+1; mid.height=Math.max(mid.left.height,x.height)+1; return mid; } private AVLNode<T> R(AVLNode<T> x){ AVLNode<T> mid=x.right; x.right=mid.left; mid.left=x; x.height=Math.max(h(x.left),h(x.right))+1; mid.height=Math.max(mid.right.height,x.height)+1; return mid; } private AVLNode<T> LR(AVLNode<T> x) { x.left=R(x.left); return L(x); } private AVLNode<T> RL(AVLNode<T> x){ x.right=L(x.right); return R(x); } public void add(T value) { if (value==null){ throw new RuntimeException("data can\'t not be null "); } this.root=insert(value,root); } private AVLNode<T> insert(T value, AVLNode<T> x) { if(x==null)x=new AVLNode<T>(value); else { //System.out.println(h(x.left)+" "+h(x.right)); if(value.compareTo(x.val)>0) { x.right=insert(value,x.right); if(h(x.right)-h(x.left)==2) { if(value.compareTo(x.right.val)>0) { x=R(x); } else { x=RL(x); } } x.height=Math.max(h(x.left),h(x.right))+1; } else if(x.val.compareTo(value)>0) { x.left=insert(value,x.left); if(h(x.right)-h(x.left)==-2) { if(value.compareTo(x.left.val)<0) { x=L(x); } else { x=LR(x); } } x.height=Math.max(h(x.left),h(x.right))+1; } else { x.height = Math.max( h(x.left), h(x.right) ) + 1; } } return x; } public void remove(T value) { if(value==null)throw new NullPointerException("No Such Value"); delete(value,root); } private AVLNode<T> delete(T value,AVLNode<T> x) { if(x==null)return null; if(value.compareTo(x.val)>0) { x.right=delete(value,x.right); if(h(x.left)-h(x.right)==2) { if(x.left.left!=null) { x=L(x); } else { x=LR(x); } } } else if(value.compareTo(x.val)<0){ x.left=delete(value,x.left); if(h(x.right)-h(x.left)==2) { if(x.right.right!=null) { x=R(x); } else { x=RL(x); } } } else if(x.right!=null){ x.val=min(x.right); x.right=delete(x.val,x.right); } else { x=x.left; } if(x!=null) x.height=Math.max(h(x.left),h(x.right))+1; return x; } private T min(AVLNode<T> x) { T ans; if(x.left!=null) { ans=min(x.left); } else { T temp=x.val; if(x.right!=null) { x=x.right; } else x=null; ans=temp; } return ans; } public AVLTree(){ root=null; } public void print() { if(root==null)throw new NullPointerException(); else { xxbl(root); } } private void xxbl(AVLNode<T> x) { // TODO Auto-generated method stub if(x==null)return; System.out.print(x.val+" "); xxbl(x.left); xxbl(x.right); } }