/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.binarySearchTrees; import xxl.core.functions.AbstractFunction; import xxl.core.functions.Function; import xxl.core.predicates.Predicate; /** * A binary tree where the absolute difference between the height of the subtrees of a Node is * limited by 1. * The AVLTree provides insertion and exact-match search in O(log(n)) time. * <br><br> * For a detailed discussion see "Introduction to Algorithms", MIT Electrical Engineering * and Computer Science, by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest. */ public class AVLTree extends BinarySearchTree { /** * Returns a Factory-Method Function (Function x Function -> BinarySearchTree) that * constructs new AVLTrees. */ public static final Function FACTORY_METHOD = new AbstractFunction() { public Object invoke (Object fixRotation, Object fixAggregate) { return new AVLTree((Predicate)fixRotation, (Function)fixAggregate); } }; /** * Nodes in a AVLTree are of the type AVLTree.Node. */ protected class Node extends BinarySearchTree.Node { /** * The height of the Node */ protected int height = 1; /** * Creates a new Node. * * @param object The object to store in the node. * @param parent The parent of the new node. */ protected Node (Object object, BinarySearchTree.Node parent) { super(object, parent); } /* (non-Javadoc) * @see xxl.core.binarySearchTrees.BinarySearchTree.Node#rotate() */ protected BinarySearchTree.Node rotate () { int index = index(); super.rotate(); refreshHeight(children[index^1]); refreshHeight(this); return this; } /* (non-Javadoc) * @see xxl.core.binarySearchTrees.BinarySearchTree.Node#fix(int) */ protected void fix (int index) { for (BinarySearchTree.Node node = this; node!=null && getHeight(node)!=refreshHeight(node);) { int balance = getHeight(node.children[1])-getHeight(node.children[0]); if (Math.abs(balance)>maxBalance) { if (getHeight((node = node.children[index = balance>0? 1: 0]).children[index^1]) > getHeight(node.children[index])) node = node.children[index^1].rotate(); node.rotate(); } node = node.parent; } } } /** * The maximum allowed balance, i.e. the maximum allowed difference in height * between the children of a node. */ protected int maxBalance; /** * Gives the height of a node. * * @param node Node of the tree. * @return The height of the given node. */ protected int getHeight (BinarySearchTree.Node node) { return node==null? 0: ((Node)node).height; } /** * Refreshes the height information of the given node. * * @param node Node of the tree. * @return The new height of the node after the refresh. */ protected int refreshHeight (BinarySearchTree.Node node) { return ((Node)node).height = 1+Math.max(getHeight(node.children[0]), getHeight(node.children[1])); } /** * Creates an AVLTree. * * @param fixAggregate Predicate that is called when an aggregate information in * the tree might be outdated. * @param fixRotation Function that is called when a rotation has occured and rotation * information in a node has to become fixed. * @param maxBalance The maximum allowed balance, i.e. the maximum allowed * difference in height between the children of a node. */ public AVLTree (Predicate fixAggregate, Function fixRotation, int maxBalance) { super(fixAggregate, fixRotation); this.maxBalance = maxBalance; } /** * Creates a AVLTree with maximum balance 1. * This constructor is equivalent to the call of * <code>AVLTree(fixAggregate,fixRotation,1)</code>. * * @param fixAggregate Predicate that is called when an aggregate information in * the tree might be outdated. * @param fixRotation Function that is called when a rotation has occured and rotation * information in a node has to become fixed. */ public AVLTree (Predicate fixAggregate, Function fixRotation) { this(fixAggregate, fixRotation, 1); } /* (non-Javadoc) * @see xxl.core.binarySearchTrees.BinarySearchTree#newNode(java.lang.Object, xxl.core.binarySearchTrees.BinarySearchTree.Node) */ public BinarySearchTree.Node newNode (Object object, BinarySearchTree.Node parent) { return new Node(object, parent); } }