/* * @(#)RedBlackTreeHead.java * * Last Modified: 9/15/01 */ import java.util.*; import java.lang.*; import java.awt.*; import java.awt.font.*; import java.awt.geom.*; /** * This class provides the head structure for a RedBlackTree. It implements the * interface for TreeHead and implements all important methods necessary for maintaining a * Red-Black Binary Search Tree. * *

Note that this implementation is not synchronized. If multiple * threads access this tree concurrently, and at least one of the threads modifies * the tree structurally, it must be synchronized externally. * @author Corey Sanders * @version 3.4 9/15/01 */ public class RedBlackTreeHead extends BSTTreeHead { /*************************************************************************/ /* BSTTreeHead constructor, methods, and variables, regardless of type. */ /*************************************************************************/ /** * String representing information regarding the type of tree. */ public static final String TREE_INFORMATION = "A red-black BST is a binary search tree in which each node is marked to be either red\n"+ "or black, with the additional restriction that no two red nodes appear consecutively on\n"+ "any path from an external link to the root (Sedgewick, 558).\n\n"+ "A balanced red-black BST is a red-black BST in which all paths from external links to\n"+ "the root have the same number of black nodes (Sedgewick, 558).\n\n"+ "Search Hits and Search Misses require about 1.002 lg N comparisons,\n"+ "on the average, in a tree built from N random keys.\n\n"+ "Search Hits and Search Misses can require 2 lg N + 2 comparisons in the worst case.\n"; /** * Constructs a new, null RedBlackTree, sorted according to the keys' natural * order. * *

Default type is BST_TREE_TYPE. */ public RedBlackTreeHead() { this(0); } /** * Constructs a new, empty RedBlackTree according to the type passed. * *@param treeType type of tree that should be implemented. */ public RedBlackTreeHead(int treeType) { super(treeType); } /** * Gets the tree type String for the BSTTree. * * @return tree type String for the tree. */ public String getTreeTypeString() { return "Red-Black Tree"; } /** ****************************************************************************** * BST_TREE_TYPE Static methods for determining best/average/worst case times * ****************************************************************************** */ /** * Returns the average Search hit time, according to n, the amount of elements in the tree. * * @param n the size of the tree for which the average search hit is needed. * * @return double the is the average search hit. */ public double averageSearchHit(int n) { return (Math.log((double)n) * 1.002); } /** * Returns the average Search miss time, according to n, the amount of elements in the tree. * * @param n the size of the tree for which the average search hit is needed. * * @return double the is the average search hit. */ public double averageSearchMiss(int n) { return (Math.log((double)n) * 1.002); } /** * Returns the worst case Search hit time, according to n, the amount of elements in the tree. * * @param n the size of the tree for which the worst case search hit is needed. * * @return double the is the worst case search hit. */ public double worstCaseSearchHit(int n) { return (Math.log((double)n) * 2 + 2); } /** * Returns the worst case Search miss time, according to n, the amount of elements in the tree. * * @param n the size of the tree for which the worst case search hit is needed. * * @return double the is the worst case search hit. */ public double worstCaseSearchMiss(int n) { return (Math.log((double)n) * 2 + 2); } /** * Returns the average Insertion time, according to n, the amount of elements in the tree. * * @param n the size of the tree for which the average search hit is needed. * * @return double the is the average search hit. */ public double averageInsertion(int n) { return (Math.log((double)n) * 1.002); } /** * Returns the worst case Insertion time, according to n, the amount of elements in the tree. * * @param n the size of the tree for which the worst case search hit is needed. * * @return double the is the worst case search hit. */ public double worstCaseInsertion(int n) { return (Math.log((double)n) * 2 + 2); } /** ********************************** * Waiting Action Method * ********************************** */ /** * Acts according to the String action passed. The method generally accompanies * a WaitingActionList which keeps the list of actions, and calls the method when * instructed to call the next action. * * @param action String action representing the next action for the BSTTreeHead. * @param elements elemetns to which the action could be occuring, depending on the type of action. */ public void waitingAction(String action, Object element) { if (action.equals(TreeHead.INSERT_NODE)) { insertAnimatingType((RedBlackTree)element); } else { super.waitingAction(action, element); } } /*-----------------------------------------------------------------------*/ /*-------------------------------BST_TREE_TYPE---------------------------*/ /*-----------------------------------START-------------------------------*/ /*-----------------------------------------------------------------------*/ /*************************************************************************/ /* BST_TREE_TYPE : Methods and Variables specific to the BST_TREE_TYPE. */ /* These methods are universally used, regardless of the type of BST. */ /*************************************************************************/ /** ************************************************************************ * BST_TREE_TYPE Original Methods(Overiden in ANIMATING_BST_TREE_TYPE * ************************************************************************ */ /** * Sets the child of the TreeHead and sets its red link to false. * * @param child Tree, beginning the Tree nodes. */ public void setChild(Tree child) { super.setChild(child); } /** * Makes and places the node into the tree. The node is returned for further manipulation. * * @param keyInsert comparable object which is added to the tree. * @param valueInsert Object that accompanies keyInsert in the node. * * @return BSTTree that was recently inserted into the tree. * * @throws ClassCastException key cannot be compared with the keys * currently in the map. */ protected BSTTree makeNodeTreeType(Comparable keyInsert, Object valueInsert) { // Get node from node factory. RedBlackTree newTree = new RedBlackTree(getTreeType()); newTree.setHead(this); // Set the null leaves. newTree.setLeaf(); ((BSTTree)newTree.getRightTree()).setHead(this); ((BSTTree)newTree.getLeftTree()).setHead(this); // Set the values of the node. newTree.setNode(keyInsert, valueInsert); return newTree; } /*-----------------------------------------------------------------------*/ /*-------------------------------BST_TREE_TYPE---------------------------*/ /*------------------------------------END--------------------------------*/ /*-----------------------------------------------------------------------*/ /*/////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ /*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\//////////////////////////////////*/ /*-----------------------------------------------------------------------*/ /*----------------------------DRAWING_BST_TREE_TYPE----------------------*/ /*-----------------------------------START-------------------------------*/ /*-----------------------------------------------------------------------*/ /*************************************************************************/ /* DRAWING_BST_TREE_TYPE : Methods and Variables specific to the */ /* DRAWING_BST_TREE_TYPE. These methods are specificaly used for drawing*/ /* to a Graphics2D. Therefore, do not use this type unless that is your */ /* purpose. */ /*************************************************************************/ /** * The current redLinkPaint (Red Default...heh heh OBVIOUSLY) */ private PaintSettings redLinkPaint = PaintSettings.getScheme(PaintSettings.RED); /** * The current redLinkStroke (BasicStroke(2.0F) Default) */ private Stroke redLinkStroke = new BasicStroke(2.0F); /** ******************************************* * DRAWING_BST_TREE_TYPE Accesssor methods * ******************************************* */ /** * Gets the red link paint for the current RedBlackTree. * * @return the paint for the red links of the drawing node. */ public PaintSettings getRedLinkPaint() { return redLinkPaint; } /** * Gets the red link stroke for the current RedBlackTree. * * @return the stroke for the red links of the drawing node. */ public Stroke getRedLinkStroke() { return redLinkStroke; } /** ******************************************* * DRAWING_BST_TREE_TYPE Mutator methods * ******************************************* */ /** * Sets the red link paint for the current RedBlackTree. * * @param redLinkPaint the paint for the red links of the drawing node. */ public void setRedLinkPaint(PaintSettings redLinkPaint) { this.redLinkPaint = redLinkPaint; } /** * Gets the red link stroke for the current RedBlackTree. * * @return the stroke for the red links of the drawing node. */ public void setRedLinkStroke(Stroke redLinkStroke) { this.redLinkStroke = redLinkStroke; } /** * Sets the NodeSettings for the entire tree from the head down. * These settings are used for drawing the node and the links of each given tree. * * @param s NodeSettings for use in drawing the entire tree. * @param k KeySettings for use in drawing the keys of the entire tree. */ public void setTreeSettings(NodeSettings s, KeySettings k, PaintSettings redLinkPaint, Stroke redLinkStroke) { if (!isDrawingBSTTree()) return; setDrawingNodeSettings(s); setDrawingKeySettings(k); setRedLinkPaint(redLinkPaint); setRedLinkStroke(redLinkStroke); if (!isTreeEmpty()) { ((RedBlackTree)getChild()).setTreeSettings(s, k, redLinkPaint, redLinkStroke); } } /*-----------------------------------------------------------------------*/ /*---------------------------ANIMATING_BST_TREE_TYPE---------------------*/ /*-----------------------------------START-------------------------------*/ /*-----------------------------------------------------------------------*/ /*************************************************************************/ /* ANIMATING_BST_TREE_TYPE : Methods and Variables specific to the */ /* ANIMATING_BST_TREE_TYPE. These methods are specificaly used for */ /* animaitng to a Graphics2D. Therefore, do not use this type unless */ /* that is your purpose. */ /*************************************************************************/ /** ********************************************* * ANIMATING_BST_TREE_TYPE Overiding methods * ********************************************* */ /** * Insert the comaparable node to the tree using its natural ordering . * *

Call to insertDrawingType * * @param node BSTTree node to be inserted into the tree * @throws ClassCastException key cannot be compared with the keys * currently in the map. */ protected void insertAnimatingType(BSTTree node) throws ClassCastException { if ((!isAnimatingBSTTree()) || (isTreeEmpty())) { ((RedBlackTree)node).setRedLink(true); insertDrawingType(node); return; } // If Animation is occuring, add ROTATE_UP to the waitingList. if (isTreeAnimating()) { getWaitingList().add(AnimatingTreeHead.INSERT_NODE, node); return; } Animation insertAnimator = makeInsertAnimation(node); // Add animation and recieve listening events. this.addTreeAnimator(insertAnimator); insertAnimator.addAnimationListener(this); // Add animation to the inserting node. node.addAnimator(insertAnimator); insertAnimator.addAnimationListener(node); // Super call insertDrawingType(node); // Add the final location, after the tree is built. ((InsertRedBlackAnimation)insertAnimator).add(node); } /** **************************************************** * ANIMATING_BST_TREE_TYPE Constructing Animations * **************************************************** */ /** * Makes an insert Animation using the given node. The Animation adds no listeners, making * the client have to add the listeners. * * @param insertNode BSTTree node that the insert Animation is built for. * @return Animation that represents the insertAnimation. */ public Animation makeInsertAnimation(BSTTree insertNode) { if (!isAnimatingBSTTree()) { return null; } // Head node (backup test). if (insertNode == this) return null; // Construct animation for Insert. InsertRedBlackAnimation newAnimator = new InsertRedBlackAnimation(insertNode,getInsertNodeLeftSettings(),getInsertNodeRightSettings(),getInsertAnimatorNodeSettings(), getInsertAnimatorKeySettings(), getTreeStatus(), getTreeAnimationStepSize()); // Starting Animation. //AffineTransform a = AffineTransform.getScaleInstance(getScreenBounds().getWidth() * .35, getScreenBounds().getHeight() * .35); // Add initial animation. //newAnimator.add(a); // Recursive call to insert the tree, starting at the head level. ((RedBlackTree)getChild()).makeInsertAnimation(insertNode, newAnimator); return newAnimator; } /** * Makes a delete Animation using the given node. The Animation adds no listeners, making * the client have to add the listeners. * * @param node BSTTree node that the deletion Animation is built from. * @return Animation that represents the deleteAnimation. */ public Animation makeDeletionAnimation(BSTTree node) { if (!isAnimatingBSTTree()) { return null; } // If this is the node to be deleted (precautionary check). if (node == this) return null; // New deletion animation. DeleteRedBlackAnimation newAnimator = new DeleteRedBlackAnimation(node, getDeleteLeftLinePaintSettings(), getDeleteRightLinePaintSettings(), getTreeStatus(), getTreeAnimationStepSize()); return newAnimator; } }