数组为{1,2,3}类型的 五种类型四种调整
一、LL型:
/**
* 带左子树旋转,适用于LL型
*/
public static AvlNode rotateWithLeftChild(AvlNode n) {
AvlNode k = n.left;
n.left = k.right;
k.right = n;
n.height = Math.max(height(n.left), height(n.right)) + 1;
k.height = Math.max(height(k.left), n.height) + 1;
return k;
}
二、RR型:
/**
* 带右子树旋转,适用于RR型
*/
public static AvlNode rotateWithRightChild(AvlNode n) {
AvlNode k = n.right;
n.right = k.left;
k.left = n;
n.height = Math.max(height(n.left), height(n.right)) + 1;
k.height = Math.max(height(k.right), n.height) + 1;
return k;
}
三、LR型:
/**
* 双旋转,适用于LR型
*/
public static AvlNode doubleWithLeftChild(AvlNode n) {
n.left = rotateWithRightChild(n.left);
return rotateWithLeftChild(n);
}
四、RL型:
/**
* 双旋转,适用于RL型
*/
public static AvlNode doubleWithRightChild(AvlNode n) {
n.right = rotateWithLeftChild(n.right);
return rotateWithRightChild(n);
}
四种类型最终都变为:
声明树的节点类:
package TN;
public class AvlNode {
public Integer num;
public int height;
public String name;
public AvlNode left,right,pre;
AvlNode(){
pre=left=right=null;
height = 0;
}
AvlNode(Integer num,String name){
this.num=num;
this.name=name;
pre=left=right=null;
height = 0;
}
@Override
public String toString() {
return "AvlNode [num=" + num + ", height=" + height + ", name=" + name + ", left=" + left + ", right=" + right
+ ", pre=" + pre + "]";
}
}
操作类:
package TN;
import TN.AvlNode;
public class AvlTree {
private static AvlNode root;// AVL树根
/**
* 初始化树
*/
public AvlTree() {
root =new AvlNode(1,"我是1");
}
//求树的高度
public static int height(AvlNode n) {
return n == null ? -1 : n.height;
}
/**
* 带左子树旋转,适用于LL型
*/
public static AvlNode rotateWithLeftChild(AvlNode n) {
AvlNode k = n.left;
n.left = k.right;
k.right = n;
n.height = Math.max(height(n.left), height(n.right)) + 1;
k.height = Math.max(height(k.left), n.height) + 1;
return k;
}
/**
* 带右子树旋转,适用于RR型
*/
public static AvlNode rotateWithRightChild(AvlNode n) {
AvlNode k = n.right;
n.right = k.left;
k.left = n;
n.height = Math.max(height(n.left), height(n.right)) + 1;
k.height = Math.max(height(k.right), n.height) + 1;
return k;
}
/**
* 双旋转,适用于LR型
*/
public static AvlNode doubleWithLeftChild(AvlNode n) {
n.left = rotateWithRightChild(n.left);
return rotateWithLeftChild(n);
}
/**
* 双旋转,适用于RL型
*/
public static AvlNode doubleWithRightChild(AvlNode n) {
n.right = rotateWithLeftChild(n.right);
return rotateWithRightChild(n);
}
/**
* 判断是否为空
*/
public static boolean isEmpty() {
return root == null;
}
/**
* 排序输出AVL树, 采用中序输出
*/
public static void printTree() {
if (isEmpty())
System.out.println("Empty tree");
else
printTree(root);
}
/**
* 中序遍历AVL树
*/
private static void printTree(AvlNode n) {
if (n != null) {
printTree(n.left);
System.out.print(n.num + " ");
printTree(n.right);
}
}
/**
* 在AVL树中插入数据
*/
public static void insert(Integer x,String name) {
root = insert(x, name,root);
}
public static AvlNode insert(Integer num,String name,AvlNode root) {
if (root == null) {
return new AvlNode(num,name);
}
int compareResult = num.compareTo(root.num);
if (compareResult < 0) {
root.left = insert(num,name, root.left);// 将x插入左子树中
if (height(root.left) - height(root.right) == 2)// 打破平衡
if (num.compareTo(root.left.num) < 0)// LL型(左左型)
root = rotateWithLeftChild(root);
else
root = doubleWithLeftChild(root); // LR型(左右型)
} else if (compareResult > 0) {
root.right = insert(num,name, root.right);// 将x插入右子树中
if (height(root.right) - height(root.left) == 2)// 打破平衡
if (num.compareTo(root.right.num) > 0)
root = rotateWithRightChild(root);// RR型(右右型)
else
root = doubleWithRightChild(root);// RL型
} else
; // 重复数据,什么也不做
root.height = Math.max(height(root.left), height(root.right)) + 1;// 更新高度
return root;
}
public static AvlNode find(AvlNode root,Integer num) {
AvlNode point=new AvlNode();
//AvlNode copy=new AvlNode();
point=root;
while(point != null) {
if(num==point.num) {
return point;
}
else if(num>point.num) {
if(point.right==null) {
System.out.println("该学生不存在");
return null;
}
else
point=point.right;
}
else {
if(point.left==null) {
System.out.println("该学生不存在");
return null;
}
else
point=point.left;
}
}
return null;
}
/**
* 在AVL树中删除
*/
public static void delete(Integer x) {
root = delete(root,x);
}
public static AvlNode delete(AvlNode root,Integer num) {//height
AvlNode point=null;
if(root == null){ // 没有找到删除的节点
return null;
}
if(num < root.num){ // 在左子树上删除
root.left = delete(root.left, num);
if(height(root.right) - height(root.left) > 1){ // 在左子树上删除,右子树高度一定不小于左子树高度
if(height(root.right.left) > height(root.right.right)){
root = doubleWithRightChild(root);//RL
}else{
root = rotateWithRightChild(root);//RR
}
}
}
else if(num == root.num){ // 找到删除的节点
if(root.left != null && root.right != null){ // 删除的节点既有左子树又有右子树
point=root.right;
while(point.left!=null)
point=point.left;
root.num = point.num; // 将失衡点的num域更改为其直接后继节点的num域
root.name = point.name;
root.right = delete(root.right, root.num); // 将问题转换为删除其直接后继节点
}else{ // 只有左子树或者只有右子树或者为叶子结点的情况
root = (root.left == null) ? root.right : root.left;
}
}
else{ // 在root的右子树上查找删除节点
root.right = delete(root.right, num);
if(height(root.left) - height(root.right) > 1){
if(height(root.left.left) > height(root.left.right)){
root =rotateWithLeftChild(root);//LL
}else{
root = doubleWithLeftChild(root);//LR
}
}
}
if(root != null){ // 更新root的高度值
root.height = Math.max(height(root.left), height(root.right)) + 1;
}
return root;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//增加
Integer[] arr = {1,2,3,4,5,6,7,8,9,10,11,12,13};
for(int i=0;i<arr.length;i++) {
AvlTree.insert(arr[i],"我是"+arr[i]);
}
//中序遍历
AvlTree.printTree();
System.out.println();
//查询
AvlNode find=find(root,12);
System.out.println(find.name);
//删除
AvlTree.delete(12);
AvlTree.printTree();
}
}