AVL树

AVL树:是带有平衡条件的二叉查找树,且左右子节点的树深度相差不超过1;在插入元素的时候可能会破坏原来AVL树的平衡,此时就需要通过旋转来解决平衡问题.在插入以后,只有那些从插入点到根节点的路径上的节点的平衡可能被破坏,因为只有这些节点的子树可能发生变化.所以当我们沿着这条路径上行并更新平衡信息时,可以发现一个节点,它的平衡破坏了AVL条件.此时将第一个这样的节点称为α,插入情况如下:

①.对α的左儿子的左子树进行一次插入(单旋转)

②.对α的左儿子的右子树进行一次插入(双旋转)

③.对α的右儿子的左子树进行一次插入(双旋转)

④.对α的右儿子的右字数进行一次插入(单旋转)

单旋转:


k2为从插入的节点往上寻找,满足第一个左右子树不平衡的节点,k1,为其对应的子节点(左节点或者右节点);旋转过程可以认为拎着k1抖,然后左右的重量就相仿了,达到了平衡的条件.





/**
 * 
 * 2016-3-13
 * @author sima
 * @param <T>
 */
public class AVLTree<T extends Comparable<T>> {
	private static class AVLNode<T>{
		@SuppressWarnings("unused")
		public AVLNode(T element) {
			this(element, null, null);
		}
		public AVLNode(T ele,AVLNode<T> left,AVLNode<T> right) {
			this.element = ele;
			this.left = left;
			this.right = right;
			this.length =  0 ;
		}
		
		T element;
		AVLNode<T> left;
		AVLNode<T> right;
		int length;
	}
	private int length(AVLNode<T> node){
		return node == null ? -1 : node.length;
	}
	
	private AVLNode<T> insert(T ele,AVLNode<T> tree){
		if(tree == null)
			return new AVLNode<T>(ele, null, null);
		int compareResult = ele.compareTo(tree.element);
		if(compareResult < 0){
			tree.left = insert(ele, tree.left);
			if(length(tree.left) - length(tree.right) == 2)
				if( ele.compareTo(tree.element) < 0)
					tree = rotateWithLeftChild(tree);// 该节点是插入到左节点的左子树上,所以单旋转即可完成调整,
				else
					tree = doubleWithLeftChild(tree);
		}else if(compareResult > 0){
			tree.right = insert(ele, tree.right);
			if(length(tree.right) - length(tree.left) == 2)
				if(ele.compareTo(tree.element) > 0)
					tree = rotateWithRightChild(tree);
				else
					tree = doubleWithRightChild(tree);
		}else
			;
		tree.length = Math.max(tree.right.length, tree.left.length) + 1;
		return tree;
	}
	
	private AVLNode<T> doubleWithRightChild(AVLNode<T> k3) {
		// TODO Auto-generated method stub
		return null;
	}
	/**
	 *  在右子树插入右节点的时候单旋转...
	 * rotateWithRightChild
	 * @param tree
	 */
	private AVLNode<T> rotateWithRightChild(AVLNode<T> k2) {
		AVLNode<T> k1 = k2.right;
		k2.right = k1.left;
		k1.left = k2;
		k2.length = Math.max(k2.left.length, k2.right.length) + 1;
		k1.length = Math.max(k2.length, k1.left.length) + 1;
		return k1;
	}

	/**
	 * 双旋转...
	 * doubleWithLeftChild
	 * @param tree
	 * @throws ClassNotFoundException 
	 * @throws SQLException 
	 */
	private AVLNode<T> doubleWithLeftChild(AVLNode<T> k3) {
		k3.left = rotateWithLeftChild(k3.left);
		return rotateWithLeftChild(k3);
	}

	/**
	 * 左子树插入左节点的时候单旋转...
	 * rotateWithLeftChild
	 * @param tree
	 */
	private AVLNode<T> rotateWithLeftChild(AVLNode<T> k2) {
		AVLNode<T> k1 = k2.left;
		k2.left = k1.right;  // k1 变为原来k2这棵树的根节点.
		// 因为k1.right > k1 < k2,所以把k2.left = k1.right
		k1.right = k2;  //k2 设置为新树的右节点.
		//重新设置k1,k2 的深度.
		k2.length = Math.max(k2.left.length, k2.right.length) + 1;
		k1.length = Math.max(k2.length, k1.left.length) + 1;
		return k1;
	}
	
}










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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值