AVLTree的构建,java实现

AVLTree

  • 是一种自平衡的二叉查找树,平衡表示其每个节点的左右子树的高度差最多为一,可以减少检索是由于极端情况产生的消耗
  • 实现的过程中需注意在插入和删除的过程维持平衡
  • 维持平衡的情况
  • 双旋转双旋转
  • 单旋转
    单旋转
package com.ccy.tree;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

public class MyAvlTree <E  extends Comparable<E>>{
	
	/**
	 * 节点类
	 * @author ccy
	 *
	 * @param <E>
	 */
	private static class TreeNode<E>{
		E value;	//数据
		TreeNode<E> left;	//左子节点
		TreeNode<E> right;	//右子节点
		int height;		//高度
		
		public TreeNode(E value,TreeNode left,TreeNode right) {
			this.left = left;
			this.right = right;
			this.value = value;
		}
		
		public TreeNode(E value) {
			this.left = null;
			this.right = null;
			this.value = value;
		}
	}
	
	private static final int ALLOW_IMBALANCE = 1;
	
	//定义根结点
	private TreeNode<E> root = null;
	
	/**
	 * 返回一个根结点为空的树
	 */
	public MyAvlTree(){
		root=null;
	}
	
	
	/**
	 * 判断是否为空
	 * @return 空为true,非空为false
	 */
	public boolean isEmpty() {
		return root == null;
	}
	
	public void insert(E value) {
		root = insert(value, root);
	}
	
	/**
	 * 添加节点
	 * @param value 想要添加到树中的数据
	 */
	private TreeNode<E> insert(E value,TreeNode<E> treeNode) {
		if(treeNode==null)
			return new TreeNode<>(value);
		if(value.compareTo(treeNode.value)>0)
			treeNode.right = insert(value, treeNode.right);
		else if(value.compareTo(treeNode.value)<0)
			treeNode.left = insert(value, treeNode.left);
		return balance(treeNode);		
	}
	/**
	 * 建立平衡
	 * @param treeNode
	 * @return
	 */
	private TreeNode<E> balance(TreeNode<E> treeNode){
		
		if(treeNode == null)
			return treeNode;
		if(height(treeNode.left)-height(treeNode.right)>ALLOW_IMBALANCE) {
			if(height(treeNode.left.left)>=height(treeNode.left.right))
				treeNode = rotateWithLeft(treeNode);
			else {
				treeNode = doubleWithLeft(treeNode);
			}
		}
		else if(height(treeNode.right)-height(treeNode.left)>ALLOW_IMBALANCE) {
			if(height(treeNode.right.right)>=height(treeNode.right.left))
				treeNode = rotateWithRight(treeNode);
			else {
				treeNode = doubleWithRight(treeNode);
			}
		}
		treeNode.height = Math.max(height(treeNode.left), height(treeNode.right))+1;
		return treeNode;
	}
	
	private int height(TreeNode<E> treeNode) {
		return treeNode==null?-1:treeNode.height;
	}
	
	/**
	 * 将左子树一次单旋上提
	 * 
	 * @param treeNode 需维持部分的部分树的根
	 * @return 单旋转后该部分树的根
	 */
	private TreeNode<E> rotateWithLeft(TreeNode<E> treeNode){
		TreeNode<E> tmpNode = treeNode.left;
		treeNode.left = tmpNode.right;
		tmpNode.right = treeNode;
		//重新对高赋值
		treeNode.height = Math.max(height(treeNode.left), height(treeNode.right))+1;
		tmpNode.height = Math.max(height(tmpNode.left), treeNode.height)+1;
		return tmpNode;
	}
	
	/**
	 * 将右子树一次单旋上提
	 * 
	 * @param treeNode 需维持部分的部分树的根
	 * @return 单旋转后该部分树的根
	 */
	private TreeNode<E> rotateWithRight(TreeNode<E> treeNode){
		TreeNode<E> tmpNode = treeNode.right;
		treeNode.right = tmpNode.left;
		tmpNode.left = treeNode;
		//重新对高赋值
		treeNode.height = Math.max(height(treeNode.left), height(treeNode.right))+1;
		tmpNode.height = Math.max(height(tmpNode.right), treeNode.height)+1;
		return tmpNode;
	}
	/**
	 * 
	 * @param treeNode
	 * @return
	 */
	private TreeNode<E> doubleWithLeft(TreeNode<E> treeNode) {
		treeNode.left = rotateWithRight(treeNode.left);
		return rotateWithLeft(treeNode);
	}
	
	private TreeNode<E> doubleWithRight(TreeNode<E> treeNode) {
		treeNode.right = rotateWithLeft(treeNode.right);
		return rotateWithRight(treeNode);
	}
	
	public void remove(E value) {
		
		root = remove(value, root);
		
	}
	/**
	 * 从AVLTree中移除一个元素
	 * 思想:
	 * 1. 先定位到该元素,若无该元素,直接返回
	 * 2. 从该元素的右子树中找出一个最小值顶替该元素,而后从其右子树中删除该最小值
	 * 3. 过程中应注意保持平衡
	 * 
	 * @param value
	 * @param treeNode
	 * @return
	 */
	private TreeNode<E> remove(E value,TreeNode<E> treeNode){
		if(treeNode == null)
			return treeNode;
		if(value.compareTo(treeNode.value)<0)
			treeNode.left = remove(value, treeNode.left);
		else if(value.compareTo(treeNode.value)>0)
			treeNode.right = remove(value, treeNode.right);
		else if(null != treeNode.left && null != treeNode.right) {
			treeNode.value = findMin(treeNode.right).value;
			treeNode.right = remove(treeNode.value, treeNode.right);
		}else
			treeNode = treeNode.left == null? treeNode.right:treeNode.left;
		return balance(treeNode);
	}
	
	
	private TreeNode<E> findMin(TreeNode<E> treeNode) {
		if(treeNode == null)
			return null;
		if(treeNode.left == null)
			return treeNode;
		return findMin(treeNode.left);
	}


	/**
	 * 广度优先遍历整棵avl树
	 * 
	 */
	public void print() {
		Queue<TreeNode> queue = new ArrayBlockingQueue<MyAvlTree.TreeNode>(20);
		queue.add(root);
		while(!queue.isEmpty()) {
			TreeNode<E> tmpNode = queue.remove();
			System.out.println(tmpNode.value);
			if(tmpNode.left!=null)
				queue.add(tmpNode.left);
			if(tmpNode.right!=null)
				queue.add(tmpNode.right);
		}
	}
}

发布了17 篇原创文章 · 获赞 1 · 访问量 653

猜你喜欢

转载自blog.csdn.net/c_c_y_CC/article/details/88996403
今日推荐