平衡二叉树(AVL Tree)的JAVA实现

当二叉树插入、删除节点时导致不满足二叉树的性质,需要通过一定的旋转使二叉树重新平衡来满足二叉树的性质

LR - 左旋

RR - 右旋

/**
* 平衡二叉树
*/
public class AVLTree {

    private TreeNode root;

    public static final int ALLOWED_IMBALANCE = 1;

    /**
    * 插入
    */	
    public void insert(int value){
	root = insert(value, root);
    }
    
    /**
    * 插入
    */
    public TreeNode insert(int value, TreeNode node){
        if(node == null){
            return new TreeNode(value, 1);
        }    
        if(value < node.value){
	    node.left = insert(value, node.left);
        }else if(value > node.value){
	    node.right = insert(value, node.right);
        }
	return balance(node);
    }

    /**
    * 平衡
    */
    public TreeNode balance(TreeNode node){
        if(node == null){
	    return null;
        }
        TreeNode left = node.left;
        TreeNode right = node.right;
	if(height(left) - height(right) > ALLOW_IMBALANCE){
	    if(height(left.left) > height(left.right)){
                //LL
		node = LL(node);
	    }else {
		//LR
	        node = LR(node);
	    }
	}else if(height(right) - height(left) > ALLOW_IMBALANCE){
	    if(height(right.right) > height(right.left)){
	        //RR
		node = RR(node);
	    }else {
		//RL
		node = RL(node);
	    }
	}
	node.height = Math.max(height(node.left), height(node.right)) + 1;
	return node;
    }

    /**
    * 高度
    */
    public static int height(TreeNode node){
	return node == null ? 0 : node.height;
    }

    /**
    * LL
    */
    public static TreeNode LL(TreeNode node){
	TreeNode newRoot = node.left;
        TreeNode newRootRightChild = newRoot.right;
	node.left = newRootRightChild;
	newRoot.right = node;

	node.height = Math.max(height(node.left), height(node.right)) + 1;
	newRoot.height = Math.max(height(newRoot.left), height(newRoot.right)) + 1;
	
	return newRoot;
    }

    /**
    * RR
    */
    public static TreeNode RR(TreeNode node) {
	TreeNode newRoot = node.right;
	TreeNode newRootLeftRightChild = newRoot.left;
	newRoot.left = node;
	node.right = newRootLeftRightChild;

	node.height = Math.max(height(node.left), height(node.right)) + 1;
	newRoot.height = Math.max(height(newRoot.left), height(newRoot.right)) + 1;

	return newRoot;
    }

    /**
    * LR
    */
    public static TreeNode LR(TreeNode node) {
        node.left = RR(node.left);
        return LL(node);
    }

    /**
    * RL
    */
    public static TreeNode RL(TreeNode node) {
        node.right = LL(node.right);
        return RR(node);
    }

    /**
    * 最大
    */
    public TreeNode max(){
        return max(this.root);
    }    

    public static TreeNode max(TreeNode node){
        if(node == null){
            return null;
        }
	TreeNode current = node;
	while(current.right != null){
	    current = current.right;
	}
	return current;
    }

    /**
    * 最小
    */
    public TreeNode min(){
        return min(this.root);
    }    

    public static TreeNode min(TreeNode node){
        if(node == null){
            return null;
        }
	TreeNode current = node;
	while(current.left!= null){
	    current = current.left;
	}
	return current;
    }

    /**
    * 删除节点
    */    
    public void delete(int value){
        if(this.root != null){
            return;
        }
        this.root = delete(value, this.root);
    }

    public static TreeNode delete(int value, TreeNode node){
	if(node == null){
	    return null;
        }
	if(value < node.value){
	    node.left = delete(value, node.left);
	}else if(value > node.value){
	    node.right = delete(value, node.right);
	}else {
	    TreeNode left = node.left;
	    TreeNode right = node.right;
	    if(left == null && right == null){
		return null;
	    }else if(left != null && right != null){
	        TreeNode leftMaxNode = max(node.left);
		leftMaxNode.right = right;
		node = left;
	    }else {
		node = node.left != null ? node.left : node.right;
	    }
	}
	return balance(node);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值