java平衡二叉树的增加删除等基本操作和代码实现

数组为{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();
 
		
		
	}
 
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值