timeBench.data.util.RedBlackTree Maven / Gradle / Ivy
/************************************************************************
*
* 1. This software is for the purpose of demonstrating one of many
* ways to implement the algorithms in Introduction to Algorithms,
* Second edition, by Thomas H. Cormen, Charles E. Leiserson, Ronald
* L. Rivest, and Clifford Stein. This software has been tested on a
* limited set of test cases, but it has not been exhaustively tested.
* It should not be used for mission-critical applications without
* further testing.
*
* 2. McGraw-Hill licenses and authorizes you to use this software
* only on a microcomputer located within your own facilities.
*
* 3. You will abide by the Copyright Law of the United Sates.
*
* 4. You may prepare a derivative version of this software provided
* that your source code indicates that it based on this software and
* also that you have made changes to it.
*
* 5. If you believe that you have found an error in this software,
* please send email to [email protected]. If you have a
* suggestion for an improvement, please send email to
* [email protected].
*
***********************************************************************/
package timeBench.data.util;
import java.awt.Color;
import java.util.Dictionary;
/**
* Implements the {@link Dictionary} interface as a red-black tree
* from Chapter 13 of Introduction to Algorithms, Second
* edition. Objects inserted into a red-black tree must implement the
* Comparable
interface.
*/
class RedBlackTree extends BinarySearchTree
{
/** Color for a red node. */
protected static final Color RED = Color.red;
/** Color for a black node. */
protected static final Color BLACK = Color.black;
/**
* Inner class for a red-black tree node. Extends a binary search
* tree node with an additional color field.
*/
protected class Node extends BinarySearchTree.Node
{
/** The node's color, either RED or BLACK. */
protected Color color;
/**
* Initializes a node with the data, makes other pointers nil,
* and makes the node red.
*
* @param data Data to save in the node.
*/
public Node(int row)
{
super(row);
this.color = RED;
}
/**
* Returns the data
instance variable of this
* node and this node's color as a String
.
*/
public String toString()
{
return super.toString() + ", " + (color == RED ? "red" : "black");
}
}
/**
* Set the sentinel nil
to a given node, and make the
* sentinel black.
*
* @param node The node that nil
is set to.
*/
protected void setNil(Node node)
{
node.color = BLACK;
super.setNil(node);
}
/**
* Creates a red-black tree with just a nil
, which is
* the root.
*/
public RedBlackTree()
{
setNil(new Node(-1));
root = nil;
}
/**
* Performs a left rotation on a node, making the node's right
* child its parent.
*
* @param x The node.
*/
protected void leftRotate(Node x)
{
Node y = (Node) x.right;
// Swap the in-between subtree from y to x.
x.right = y.left;
if (y.left != nil)
y.left.parent = x;
// Make y the root of the subtree for which x was the root.
y.parent = x.parent;
// If x is the root of the entire tree, make y the root.
// Otherwise, make y the correct child of the subtree's
// parent.
if (x.parent == nil)
root = y;
else
if (x == x.parent.left)
x.parent.left = y;
else
x.parent.right = y;
// Relink x and y.
y.left = x;
x.parent = y;
}
/**
* Performs a right rotation on a node, making the node's left
* child its parent.
*
* @param x The node.
*/
protected void rightRotate(Node x)
{
Node y = (Node) x.left;
x.left = y.right;
if (x.left != null)
y.right.parent = x;
y.parent = x.parent;
y.right = x;
x.parent = y;
if (root == x)
root = y;
else
if (y.parent.left == x)
y.parent.left = y;
else
y.parent.right = y;
}
/**
* Inserts a node into the tree.
*
* @param z The node to insert.
*/
protected void treeInsert(Node z)
{
super.treeInsert(z);
insertFixup(z);
}
/**
* Restores the red-black conditions of the tree after inserting a
* node.
*
* @param z The node inserted.
*/
protected void insertFixup(Node z)
{
Node y = null;
while (((Node) z.parent).color == RED) {
if (z.parent == z.parent.parent.left) {
y = (Node) z.parent.parent.right;
if (y.color == RED) {
((Node) z.parent).color = BLACK;
y.color = BLACK;
((Node) z.parent.parent).color = RED;
z = (Node) z.parent.parent;
}
else {
if (z == z.parent.right) {
z = (Node) z.parent;
leftRotate(z);
}
((Node) z.parent).color = BLACK;
((Node) z.parent.parent).color = RED;
rightRotate((Node) z.parent.parent);
}
}
else {
y = (Node) z.parent.parent.left;
if (y.color == RED) {
((Node) z.parent).color = BLACK;
y.color = BLACK;
((Node) z.parent.parent).color = RED;
z = (Node) z.parent.parent;
}
else {
if (z == z.parent.left) {
z = (Node) z.parent;
rightRotate(z);
}
((Node) z.parent).color = BLACK;
((Node) z.parent.parent).color = RED;
leftRotate((Node) z.parent.parent);
}
}
}
((Node) root).color = BLACK;
}
/**
* Removes a node from the tree.
*
* @param node The node to be removed.
* @throws DeleteSentinelException if there is an attempt to
* delete the sentinel nil
.
* @throws ClassCastException if node
does not
* reference a Node
object.
*/
public void delete(Object handle)
{
Node z = (Node) handle;
Node y = z;
Node x = (Node) nil;
// Do not allow the sentinel to be deleted.
if (z == nil)
throw new RuntimeException("can't delete nil");
if (z.left != nil && z.right != nil)
y = (Node) successor(z);
if (z.left != nil)
x = (Node) y.left;
else
x = (Node) y.right;
x.parent = y.parent;
if (y.parent == nil)
root = x;
else
if (y == y.parent.left)
y.parent.left = x;
else
y.parent.right = x;
if (y != z) {
y.left = z.left;
y.left.parent = y;
y.right = z.right;
y.right.parent = y;
y.parent = z.parent;
if (z == root)
root = y;
else
if (z == z.parent.left)
z.parent.left = y;
else
z.parent.right = y;
}
if (y.color == BLACK)
deleteFixup(x);
}
/**
* Restores the red-black properties of the tree after a deletion.
*
* @param x Node at which there may be a violation.
*/
protected void deleteFixup(Node x)
{
while (x != root && x.color == BLACK) {
if (x.parent.left == x) {
Node w = (Node) x.parent.right;
if (w.color == RED) {
w.color = BLACK;
((Node) x.parent).color = RED;
leftRotate((Node) x.parent);
w = (Node) x.parent.right;
}
if (((Node) w.left).color == BLACK
&& ((Node) w.right).color == BLACK) {
w.color = RED;
x = (Node) x.parent;
}
else {
if (((Node) w.right).color == BLACK) {
((Node) w.left).color = BLACK;
w.color = RED;
rightRotate(w);
w = (Node) x.parent.right;
}
w.color = ((Node) x.parent).color;
((Node) x.parent).color = BLACK;
((Node) w.right).color = BLACK;
leftRotate((Node) x.parent);
x = (Node) root;
}
}
else {
Node w = (Node) x.parent.left;
if (w.color == RED) {
w.color = BLACK;
((Node) x.parent).color = RED;
rightRotate((Node) x.parent);
w = (Node) x.parent.left;
}
if (((Node) w.right).color == BLACK
&& ((Node) w.left).color == BLACK) {
w.color = RED;
x = (Node) x.parent;
}
else {
if (((Node) w.left).color == BLACK) {
((Node) w.right).color = BLACK;
w.color = RED;
leftRotate(w);
w = (Node) x.parent.left;
}
w.color = ((Node) x.parent).color;
((Node) x.parent).color = BLACK;
((Node) w.left).color = BLACK;
rightRotate((Node) x.parent);
x = (Node) root;
}
}
}
x.color = BLACK;
}
/**
* Returns the number of black nodes from a given node down to any
* leaf. The value should be the same for all paths.
*
* @param z The node.
* @throws BlackHeightException if the number of black nodes on a
* path from the left child down to a leaf differs from the number
* of black nodes on a path from the right child down to a leaf.
*/
public int blackHeight(Node z)
{
if (z == nil)
return 0;
int left = blackHeight((Node) z.left);
int right = blackHeight((Node) z.right);
if (left == right)
if (z.color == BLACK)
return left + 1;
else
return left;
else
throw new RuntimeException();
}
/**
* Returns the number of black nodes from the root down to any
* leaf. The value should be the same for all paths.
*
* @param z The node.
* @throws BlackHeightException if the number of black nodes on a
* path from the left child down to a leaf differs from the number
* of black nodes on a path from the right child down to a leaf.
*/
public int blackHeight()
{
return blackHeight((Node) root);
}
}
// $Id: RedBlackTree.java,v 1.1 2003/10/14 16:56:20 thc Exp $
// $Log: RedBlackTree.java,v $
// Revision 1.1 2003/10/14 16:56:20 thc
// Initial revision.
//
© 2015 - 2025 Weber Informatics LLC | Privacy Policy