对平衡二叉树的增加和删除

import java.util.ArrayList;
import java.util.Scanner;

public class LearnAVL {
	private static ArrayList<AvlNode> queue;
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		queue=new ArrayList<AvlNode>();
		Scanner read=new Scanner(System.in);
		String str=read.nextLine();
		String strr[]=str.split(" ");
		AvlNode root=new AvlNode(Integer.valueOf(strr[0]));
		System.out.println(strr.length);
		//测试数据
		for(int i=1;i<strr.length;i++){
			root=insert(Integer.valueOf(strr[i]),root);
		}
		root=delete(root,Integer.valueOf(strr[0]));
		queue.add(root);
		//打印树 层次遍历
		pfs();
	}
	public static AvlNode insert(int x,AvlNode t){
		if(t==null){
			return new AvlNode(x);
		}
		int comparaResult=t.compareTo(x);
		if(comparaResult>0){
			//小于当前值,插在左边
			t.left=insert(x,t.left);
			comparaResult=t.left.compareTo(x);
			if(getHeight(t.left)-getHeight(t.right)>1){
				if(t.left.compareTo(x)>0){
					t=rotateLeft(t);
				}else{
					t=doubleRotateLeft(t);
				}
			}
		}else if(comparaResult<0){
			//大于当前值,插在右边
			t.right=insert(x,t.right);
			comparaResult=t.right.compareTo(x);
			if(getHeight(t.right)-getHeight(t.left)>1){
				if(t.right.compareTo(x)<0){
					t=rotateRight(t);
				}else{
					t=doubleRotateRight(t);
				}
				
			}
		}else{
			return t;
		}
		t.height=Math.max(getHeight(t.right), getHeight(t.left))+1;
		return t;
	}
	private static AvlNode delete(AvlNode t,int x){
		if(t==null){
			return null;
		}
		int compareRes=t.compareTo(x);
		if(compareRes>0){
			t.left=delete(t.left,x);
			if(getHeight(t.right)-getHeight(t.left)>1){
				//右左  双旋转
				if(getHeight(t.right.left)>getHeight(t.right.right)){
					t=doubleRotateRight(t);
				}else{
					t=rotateRight(t);
				}
			}
		}else if(compareRes<0){
			t.right=delete(t.right,x);
			if(getHeight(t.left)-getHeight(t.right)>1){
				//左右  双旋转
				if(getHeight(t.left.right)>getHeight(t.left.left)){
					t=doubleRotateLeft(t);
				}else{
					t=rotateLeft(t);
				}
			}
		}else if(compareRes==0){
			t=null;
		}
		if(t!=null){
			t.height=Math.max(getHeight(t.left), getHeight(t.right))+1;
		}
		return t;
	}
	/**
	 * 右旋转:将t的右节点变为根节点,想象在重力的作用下,t滑落到左边,变为左节点
	 * @param t 树变为不平衡的第一个节点
	 * @return
	 */
	private static AvlNode rotateRight(AvlNode t) {
		
		AvlNode k2=t.right;
		t.right=k2.left;
		k2.left=t;
		t.height=Math.max(getHeight(t.left), getHeight(t.right))+1;
		k2.height=Math.max(getHeight(t.left), getHeight(t.right))+1;
		return k2;
	}
	/**
	 * 左旋转:同右旋转
	 * @param t 树变为不平衡的第一个节点
	 * @return
	 */
	private static AvlNode rotateLeft(AvlNode t) {
		
		AvlNode k2=t.left;
		t.left=k2.right;
		k2.right=t;
		t.height=Math.max(getHeight(t.left), getHeight(t.right))+1;
		k2.height=Math.max(getHeight(k2.right), getHeight(k2.left))+1;
		return k2;
	}
	/**
	 * 插入左子树的右子树时旋转,具体:先让右子树向左旋转(变为一个可以单旋转的左子树,即将右边的子树整合到左边),然后左子树向右旋转
	 * @param t 树变为不平衡的第一个节点
	 * @return
	 */
	private static AvlNode doubleRotateLeft(AvlNode t) {
		t.left=rotateRight(t.left);
		t=rotateLeft(t);
		return t;
	}
	/**
	 * 插入右子树的左子树时旋转,具体:先让左子树向右旋转(变为一个可以单旋转的右子树,即将左边的子树整合到右边),然后右子树向左旋转
	 * @param t 树变为不平衡的第一个节点
	 * @return
	 */
	private static AvlNode doubleRotateRight(AvlNode t) {
		t.right=rotateLeft(t.right);
		t=rotateRight(t);
		return t;
		
		
	}
	private static int getHeight(AvlNode t){
		return t==null?0:t.height;
		
	}
	private static void pfs(){
		AvlNode t;
		while(!queue.isEmpty()&&(t=queue.remove(0))!=null){
			System.out.println(t.element);
			if(t.left!=null){
				queue.add(t.left);
			}
			if(t.right!=null){
				queue.add(t.right);
			}
		}
		
	}
}
class AvlNode implements Comparable<Integer>{
	public int element,height=1;
	public AvlNode left,right;
	public AvlNode(int t){
		this(t,null,null);
	}
	public AvlNode(int t,AvlNode left ,AvlNode right){
		element=t;
		this.left=left;
		this.right=right;
	}
	@Override
	public int compareTo(Integer o) {
		// TODO 自动生成的方法存根
		if(element>o){
			return 1;
		}else if(element<o){
			return -1;
		}
		return 0;
	}
	
	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值