对旋转的图文解释::
图可以参考这个链接,这里仅提供一种思路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);
}
}