AVL树

AVL树是最先发明的自平衡二叉查找树。

特点:

  1. 任何节点的左右子树的高度相差的绝对值(平衡因子)<=1
  2. 空树的高度为0
  3. 本身首先是一棵二叉搜索树
  4. 查找、插入和删除在平均和最坏情况下都是O(logn)。

AVL树 JAVA 实现

1、节点定义

	private static class AVLTreeNode<T extends Comparable<T>> {
		
		private T element;
		private AVLTreeNode<T> leftNode;
		private AVLTreeNode<T> rightNode;
		private int height;
		
		public AVLTreeNode(T element, AVLTreeNode<T> leftNode, AVLTreeNode<T> rightNode) {
			this.element = element;
			this.leftNode = leftNode;
			this.rightNode = rightNode;
			this.height = Math.max(heightOfNode(leftNode), heightOfNode(rightNode)) + 1;
		}
		
		public AVLTreeNode(T element) {
			this(element, null, null);
		}
	}

2、AVL树的定义

public class AVLTree<T extends Comparable<T>> {
	
	private AVLTreeNode<T> rootNode;    // 根节点

}

3、旋转

// 左左旋转
	private AVLTreeNode<T> leftLeftRotation(AVLTreeNode<T> node) {
		AVLTreeNode<T> node1;
		
		node1 = node.leftNode;
		node.leftNode = node1.rightNode;
		node1.rightNode = node;
		
		node1.height = Math.max(heightOfNode(node1.leftNode), heightOfNode(node1.rightNode)) + 1;
		node.height = Math.max(heightOfNode(node.leftNode), heightOfNode(node.rightNode)) + 1;
		
		return node1;
	}

// 右右旋转
	private AVLTreeNode<T> rightRightRotation(AVLTreeNode<T> node) {
		AVLTreeNode<T> node1;
		
		node1 = node.rightNode;
		node.rightNode = node1.leftNode;
		node1.leftNode = node;
		
		node1.height = Math.max(heightOfNode(node1.leftNode), heightOfNode(node1.rightNode)) + 1;
		node.height = Math.max(heightOfNode(node.leftNode), heightOfNode(node.rightNode)) + 1;
		
		return node1;
	}

// 右左旋转
	private AVLTreeNode<T> rightLeftRotation(AVLTreeNode<T> node) {
		node.rightNode = leftLeftRotation(node.rightNode);
		return rightRightRotation(node);
	}

//左右旋转	
	private AVLTreeNode<T> leftRightRotation(AVLTreeNode<T> node) {
		node.leftNode = rightRightRotation(node.leftNode);
		return leftLeftRotation(node);
	}

4、计算节点高度

	private static int heightOfNode(AVLTreeNode node) {
		if (node == null) {
			return 0;
		}
		return node.height;
	}

5、获取AVL树的高度

	public int height() {
		return heightOfNode(this.rootNode);
	}

6、修复节点

	private AVLTreeNode<T> balance(AVLTreeNode<T> node) {
		if (node == null) {
			return null;
		}
		
		if ((heightOfNode(node.leftNode) - heightOfNode(node.rightNode)) > 1) {
			if ((heightOfNode(node.leftNode.leftNode) - heightOfNode(node.leftNode.rightNode)) >= 1) {
				// LL
				leftLeftRotation(node);
			} else {
				// LR
				rightLeftRotation(node);
			}
		} else if ((heightOfNode(node.rightNode) - heightOfNode(node.leftNode)) > 1) {
			if ((heightOfNode(node.rightNode.rightNode) - heightOfNode(node.rightNode.leftNode)) >= 1) {
				// RR
				rightRightRotation(node);
			} else {
				// RL
				leftRightRotation(node);
			}
		}
		
		node.height = Math.max(heightOfNode(node.leftNode), heightOfNode(node.rightNode)) + 1;
		return node;
	}

7、插入一个节点

	public void insert(T element) {
		if (element == null) {
			return;
		}
		rootNode = insert(element, rootNode);
	}
	
    // 给一个节点插入一个子节点
	private AVLTreeNode<T> insert(T element, AVLTreeNode<T> node) {
		if (node == null) {
			node = new AVLTreeNode<T>(element);
		}
		
		int compareResult = element.compareTo(node.element);
		if (compareResult < 0) {
			node.leftNode = insert(element, node.leftNode);
		} else if (compareResult > 0) {
			node.rightNode = insert(element, node.rightNode);
		}
		node = balance(node);
		return node;
	}

8、获取树的最大值

	public T findMaxElement() {
		return findMaxNode(rootNode).element;
	}
	
    // 获取最大的节点
	private AVLTreeNode<T> findMaxNode(AVLTreeNode<T> node) {
		if(node == null) {
			return null;
		}
		if (node.rightNode != null) {
			return findMaxNode(node.rightNode);
		} else {
			return node;
		}
	}

9、获取树的最小值

	public T findMinElement() {
		return findMinNode(rootNode).element;
	}
	
	private AVLTreeNode<T> findMinNode(AVLTreeNode<T> node) {
		if(node == null) {
			return null;
		}
		if (node.leftNode != null) {
			return findMinNode(node.leftNode);
		} else {
			return node;
		}
	}

10、根据节点的值删除一个节点

	public void remove(T element) {
		if (element == null) {
			return;
		}
		rootNode = remove(element, rootNode);
	}
	
	private AVLTreeNode<T> remove(T element, AVLTreeNode<T> node) {
		if (node == null) {
			return node;
		}
		
		int compareResult = element.compareTo(node.element);
		if (compareResult < 0) {
			node.leftNode = remove(element, node.leftNode);
		} else if (compareResult > 0) {
			node.rightNode = remove(element, node.rightNode);
		} else if (node.rightNode != null && node.leftNode != null) {
			node.element = findMinNode(node.rightNode).element;
			node.rightNode = remove(node.element, node.rightNode);
		} else {
			node = (node.rightNode == null) ? node.rightNode : node.leftNode;
		}
		return balance(node);
	}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值