JAVA实现AVL树的重构

AVL树特点

(1)每个节点的平衡因子只可能是-1,0,1(否则失衡)。
(2)每个节点的左右子树高度差不能超过1。
(3)搜索、添加、删除的时间复杂度和高度差不多为 O(log n)。

为什么使用AVL树

二叉搜索树对节点的删除和添加都有可能让二叉树退化为链表,这样二叉搜索树的高度就变得很高,直接导致了搜索、添加、删除的时间复杂度变高。
所以我们考虑再添加删除后,使用尽量少的调整让树的高度变小,达到适度的平衡。进而提高删除,搜索,添加的效率。

重构代码

AVL树是BST(二叉搜索树)的子类,BST代码在之前的文章中

import java.util.Comparator;

public class AVLTree<E> extends BST<E>{
	
	
	//构造方法
	public AVLTree(){
		this(null);
	}
	
	public AVLTree(Comparator<E> comparator) {
		super(comparator);
	}
	
	
	/*
	 一棵树是否平衡
	 */
	private boolean isBalanced(Node<E> node) {
		return Math.abs(((AVLNode<E>)node).balanceFactor()) <= 1;
	}
	
	/*
	 高度更新方法的封装
	 */
	private void updateHeight(Node<E> node) {
		((AVLNode<E>)node).updateHeight();
	}
	
	/*
	 AVL数需要有高度属性
	 AVL特有的节点
	 */
	private static class AVLNode<E> extends Node<E>{
		int height = 1;
		
		public AVLNode(E element, Node<E> parent) {
			super(element, parent);
			// TODO 自动生成的构造函数存根
		}
		
		/*
		 求平衡因子
		 */
		public int balanceFactor() {
			int leftHeight = left == null ? 0 : ((AVLNode<E>)left).height;
			int rightHeight = right == null ? 0 : ((AVLNode<E>)right).height;
			return leftHeight - rightHeight;
		}
		
		/*
		 更新高度的方法
		 */
		public void updateHeight() {
			int leftHeight = left == null ? 0 : ((AVLNode<E>)left).height;
			int rightHeight = right == null ? 0 : ((AVLNode<E>)right).height;
			height = 1 + Math.max(leftHeight, rightHeight);
		}
		/*
		 * 找比较高的子节点
		 */
		public Node<E> tallerChild(){
			int leftHeight = left == null ? 0 : ((AVLNode<E>)left).height;
			int rightHeight = right == null ? 0 : ((AVLNode<E>)right).height;
			if (leftHeight > rightHeight) {return left;}
			if (leftHeight < rightHeight) {return right;}
			//相等返回同边的
			return isLeftChild() ? left : right;
		}
	}
	
	

	
	
	
	/*
	 * 重写方法恢复平衡的逻辑
	 */
	@Override
	protected void afterAdd(Node<E> node) {
			while((node = node.parent) != null) {
				if (isBalanced(node)) {
					//更新高度
					updateHeight(node);
				}else {
					//恢复平衡
					rebalance(node);
					break;
				}
			}
	}
	
	
	/*
	 删除后恢复平衡的方法
	 */
	@Override
	protected void afterRemove(Node<E> node) {
		while((node = node.parent) != null) {
			if (isBalanced(node)) {
				//更新高度
				updateHeight(node);
			}else {
				//恢复平衡
				rebalance(node);
			}
		}
	}
	
	
	
	/*
	 恢复树平衡的逻辑
	 */
	
	private void rebalance(Node<E> grand) {
		//找高度比较高的子节点
		Node<E> parent = ((AVLNode<E>)grand).tallerChild();
		Node<E> node = ((AVLNode<E>)parent).tallerChild();
		if (parent.isLeftChild()) {// L
			if (node.isLeftChild()) {//LL
				rotateRight(grand);
			}else { //LR
				rotateLeft(parent);
				rotateRight(grand);
			}
		}else { //R
			if (node.isRightChild()) {//RR
				rotateLeft(grand);
			}else {//RL
				rotateRight(parent);
				rotateLeft(grand);
			}
		}
	}
	
	
	/*
	 统一的恢复平衡的方法
	 */
	private void rebalance2(Node<E> grand) {
		//找高度比较高的子节点
		Node<E> parent = ((AVLNode<E>)grand).tallerChild();
		Node<E> node = ((AVLNode<E>)parent).tallerChild();
		if (parent.isLeftChild()) {// L
			if (node.isLeftChild()) {//LL
				rotate(grand, node.left, node, node.right, parent, parent.right, grand, grand.right);
			}else { //LR
				rotate(grand, parent.left, parent, node.left, node, node.right, grand, grand.right);
			}
		}else { //R
			if (node.isRightChild()) {//RR
				rotate(grand, grand.left, grand, parent, parent.left, node, node.left, node.right);
			}else {//RL
				rotate(grand, grand.left, grand, node.left, node, node.right, parent, parent.right);
			}
		}
	}
	
	/*
	 统一的旋转方法
	 */
	private void rotate(
			Node<E> r, //子树根节点
			Node<E> a,Node<E> b,Node<E> c,
			Node<E> d,
			Node<E> e,Node<E> f,Node<E> g) {
		//让d成为这个子树的根节点
		d.parent = r.parent;
		if (r.isLeftChild()) {
			r.parent.left = d;
		}else if (r.isRightChild()) {
			r.parent.right = d;
		}else {
			//根节点
			root = d;
		}
		
		// a-b-c
		b.left = a;
		b.right = c;
		if (a != null) {
			a.parent = b;
		}
		if (c != null) {
			c.parent = b;
		}
		updateHeight(b);
		//e-f-g
		f.left = e;
		f.left = g;
		if (e != null) {
			a.parent = f;
		}
		if (g != null) {
			g.parent = g;
		}
		updateHeight(f);
		
		//b-d-f
		d.left = d;
		d.left = f;
		b.parent = d;
		f.parent = d;
		updateHeight(d);
	}
	
	
	
	/*
	 左旋转
	 */
	private void rotateLeft(Node<E> grand) {
		Node<E> parent = grand.right;
		Node<E> child = parent.left;
		//旋转
		grand.right = child;
		parent.left = grand;
		
		//更新父节点
		//parent
		parent.parent = grand.parent;
		if (grand.isLeftChild()) {
			grand.parent.left = parent;
		}else if (grand.isRightChild()) {
			grand.parent.right = parent;
		}else {
			//grand为根节点
			root = parent;
		}
		//grand
		grand.parent = parent;
		//node 
		if (child != null) {
			child.parent = grand;
		}
		//更新高度
		updateHeight(grand);
		updateHeight(parent);
	}
	/*
	 右旋转
	 */
	private void rotateRight(Node<E> grand) {
		Node<E> parent = grand.left;
		Node<E> child = parent.right;
		
		grand.left = child;
		parent.right = grand;
		
		parent.parent = grand.parent;
		if (grand.isLeftChild()) {
			grand.parent.left = parent;
		}else if (grand.isRightChild()) {
			grand.parent.right = parent;
		}else {
			root = parent;
		}
		
		grand.parent = parent;
		
		if (child != null) {
			child.parent = grand;
		}
		updateHeight(grand);
		updateHeight(parent);
		
	}
	
	/*
	 重写方法 创建节点
	 */
	@Override
	protected Node<E> createNode(E element, Node<E> parent) {
		return new AVLNode<E>(element, parent);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_43507104/article/details/106266902
今日推荐