home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-09-10 | 16.5 KB | 795 lines |
- // Copyright(c) 1996 ObjectSpace, Inc.
- // Portions Copyright(c) 1995, 1996 Hewlett-Packard Company.
-
- package jgl;
-
- /**
- * Tree is a red-black tree structure used as the underlying data structure by all
- * all associative containers.
- * <p>
- * @version 1.1
- * @author ObjectSpace, Inc.
- */
-
- final class TreeNode
- {
- public int color = Tree.BLACK;
- public TreeNode parent;
- public TreeNode left;
- public TreeNode right;
- public Object object;
-
- public TreeNode()
- {
- }
-
- public TreeNode( Object value )
- {
- object = value;
- }
- }
-
- final class InsertResult
- {
- public boolean ok;
- public TreeNode node;
-
- public InsertResult( TreeNode n, boolean b )
- {
- ok = b;
- node = n;
- }
- }
-
- final class Tree
- {
- public static final int RED = 1;
- public static final int BLACK = 2;
- static TreeNode NIL = new TreeNode();
- int size;
- boolean myInsertAlways;
- boolean myIsMap;
- BinaryPredicate myComparator;
- Container myContainer;
- TreeNode myHeader = new TreeNode(); // Note: myHeader == end, myHeader.left == begin
-
- Tree( boolean isMap, boolean always, Container container )
- {
- this( isMap, always, new HashComparator(), container );
- }
-
- Tree( boolean isMap, boolean always, BinaryPredicate comparator, Container container )
- {
- myContainer = container;
- myIsMap = isMap;
- myInsertAlways = always;
- myComparator = comparator;
- myHeader.color = RED;
- clear();
- }
-
- Tree( Tree tree )
- {
- myContainer = tree.myContainer;
- myIsMap = tree.myIsMap;
- myInsertAlways = tree.myInsertAlways;
- myComparator = tree.myComparator;
- myHeader.color = RED;
- copyTree( tree );
- }
-
- boolean compare( Object first, Object second )
- {
- return myComparator.execute( first, second );
- }
-
- Object key( Object object )
- {
- return myIsMap ? ((Pair) object).first : object;
- }
-
- Object value( Object object )
- {
- if ( myIsMap )
- {
- if ( object == null )
- return null;
-
- return ((Pair) object).second;
- }
- else
- {
- return object;
- }
- // return myIsMap ? ((Pair) object).second : object;
- }
-
- void copy( Tree tree )
- {
- if( this != tree )
- {
- clear();
- copyTree( tree );
- }
- }
-
- OrderedSetIterator beginSet()
- {
- return new OrderedSetIterator( this, myHeader.left, (OrderedSet)myContainer );
- }
-
- OrderedSetIterator endSet()
- {
- return new OrderedSetIterator( this, myHeader, (OrderedSet)myContainer );
- }
-
- OrderedMapIterator beginMap( int mode )
- {
- return new OrderedMapIterator( this, myHeader.left, (OrderedMap)myContainer, mode );
- }
-
- OrderedMapIterator endMap( int mode )
- {
- return new OrderedMapIterator( this, myHeader, (OrderedMap)myContainer, mode );
- }
-
- int maxSize()
- {
- return Allocator.maxSize();
- }
-
- TreeNode insert( TreeNode pos, Object value )
- {
- if( pos == myHeader.left )
- {
- if( size > 0 && compare( key( value ), key( pos.object ) ) )
- return insert( pos, pos, value );
- else
- return insert( value ).node;
- }
- else if( pos == myHeader )
- {
- if( compare( key( myHeader.right.object ), key( value ) ) )
- return insert( NIL, myHeader.right, value );
- else
- return insert( value ).node;
- }
- else
- {
- TreeNode before = decrement( pos );
-
- if( compare( key( before.object ), key( value ) ) && compare( key( value ), key( pos.object ) ) )
- if( before.right == NIL )
- return insert( NIL, before, value );
- else
- return insert( pos, pos, value );
- else
- return insert( value ).node;
- }
- }
-
- void clear()
- {
- myHeader.parent = NIL;
- myHeader.right = myHeader;
- myHeader.left = myHeader;
- size = 0;
- }
-
- Object remove( Object key )
- {
- return remove( lowerBound( key ), upperBound( key ) );
- }
-
- Object remove( TreeNode first, TreeNode last )
- {
- Object rvalue;
- if( first == myHeader.left && last == myHeader && size != 0 )
- {
- rvalue = value(first.object);
- clear();
- }
- else
- {
- TreeNode next;
- rvalue = value( first.object );
-
- while( first != last )
- {
- next = increment( first );
- remove( first );
- first = next;
- }
- }
-
- return rvalue;
- }
-
- TreeNode find( Object key )
- {
- TreeNode j = lowerBound( key );
- return ( j == myHeader || compare( key, key( j.object ) ) ) ? myHeader : j;
- }
-
- int count( Object key )
- {
- return distance( lowerBound( key ), upperBound( key ) );
- }
-
- TreeNode lowerBound( Object key )
- {
- TreeNode y = myHeader;
- TreeNode x = myHeader.parent;
- boolean comp = false;
-
- while( x != NIL )
- {
- y = x;
- comp = compare( key( x.object ), key );
- x = comp ? x.right : x.left;
- }
-
- return comp ? increment( y ) : y;
- }
-
- TreeNode upperBound( Object key )
- {
- TreeNode y = myHeader;
- TreeNode x = myHeader.parent;
- boolean comp = true;
-
- while( x != NIL )
- {
- y = x;
- comp = compare( key, key( x.object ) );
- x = comp ? x.left : x.right;
- }
-
- return comp ? y : increment( y );
- }
-
- void insert( InputIterator first, InputIterator last )
- {
- InputIterator firstx = (InputIterator) first.clone();
-
- while( !firstx.equals( last ) )
- insert( firstx.nextElement() );
- }
-
- InsertResult insert( Object value )
- {
- TreeNode y = myHeader;
- TreeNode x = myHeader.parent;
- boolean comp = true;
-
- while( x != NIL )
- {
- y = x;
- comp = compare( key( value ), key( x.object ) );
- x = comp ? x.left : x.right;
- }
-
- if( myInsertAlways )
- return new InsertResult( insert( x, y, value ), true );
-
- TreeNode j = y;
-
- if( comp )
- if ( j == myHeader.left )
- return new InsertResult( insert( x, y, value ), true );
- else
- j = decrement( j );
-
- if( compare( key( j.object ), key( value ) ) )
- return new InsertResult( insert( x, y, value ), true );
- else
- return new InsertResult( j, false );
- }
-
- InsertResult put( Object value )
- {
- TreeNode y = myHeader;
- TreeNode x = myHeader.parent;
- boolean comp = true;
-
- while( x != NIL )
- {
- y = x;
- comp = compare( key( value ), key( x.object ) );
- x = comp ? x.left : x.right;
- }
-
- TreeNode j = y;
-
- if( comp )
- if ( j == myHeader.left )
- return new InsertResult( insert( x, y, value ), true );
- else
- j = decrement( j );
-
- if( compare( key( j.object ), key( value ) ) )
- return new InsertResult( insert( x, y, value ), true );
- else
- return new InsertResult( j, false );
- }
-
- Object get( Object key )
- {
- TreeNode y = myHeader;
- TreeNode x = myHeader.parent;
- boolean comp = true;
-
- while( x != NIL )
- {
- y = x;
- comp = compare( key, key( x.object ) );
- x = comp ? x.left : x.right;
- }
-
- TreeNode j = y;
-
- if( comp )
- if ( j == myHeader.left )
- return null;
- else
- j = decrement( j );
-
- if( compare( key( j.object ), key ) )
- return null;
- else
- return ((Pair) j.object).second;
- }
-
- TreeNode insert( TreeNode x, TreeNode y, Object value )
- {
- ++size;
- TreeNode z = new TreeNode( value );
- boolean insertToLeft = ( y == myHeader || x != NIL || compare( key( value ), key( y.object ) ) );
- insert( insertToLeft, x, y, z );
- return z;
- }
-
- static int distance( TreeNode first, TreeNode last )
- {
- int n = 0;
-
- while( first != last )
- {
- first = increment( first );
- ++n;
- }
-
- return n;
- }
-
- TreeNode copyTree( TreeNode oldNode, TreeNode parent )
- {
- if( oldNode == NIL )
- return NIL;
-
- TreeNode newNode = new TreeNode( oldNode.object );
- newNode.color = oldNode.color;
- newNode.left = copyTree( oldNode.left, newNode );
- newNode.right = copyTree( oldNode.right, newNode );
- newNode.parent = parent;
- return newNode;
- }
-
- void copyTree( Tree tree )
- {
- myHeader.parent = copyTree( tree.myHeader.parent, myHeader );
- myHeader.left = minimum( myHeader.parent );
- myHeader.right = maximum( myHeader.parent );
- size = tree.size;
- }
-
- Array keys()
- {
- Array array = new Array();
- int i = 0;
- TreeNode node = myHeader.left;
-
- while( node != myHeader )
- {
- array.add( ((Pair) node.object).first );
- node = increment( node );
- }
-
- return array;
- }
-
- Array keys( Object value )
- {
- Array array = new Array();
- int i = 0;
- TreeNode node = myHeader.left;
-
- while( node != myHeader )
- {
- if( ((Pair) node.object).second.equals( value ) )
- array.add( ((Pair) node.object).first );
-
- node = increment( node );
- }
-
- return array;
- }
-
-
- Array values( Object key )
- {
- Array array = new Array();
- int i = 0;
- TreeNode node = myHeader.left;
-
- while( node != myHeader )
- {
- if( (((Pair) node.object).first).equals( key ) )
- array.add( ((Pair) node.object).second );
-
- node = increment( node );
- }
-
- return array;
- }
-
- static TreeNode increment( TreeNode node )
- {
- if( node.right != NIL )
- {
- node = node.right;
-
- while( node.left != NIL )
- node = node.left;
-
- return node;
- }
- else
- {
- while( node == node.parent.right )
- node = node.parent;
-
- return node.right == node.parent ? node : node.parent;
- }
- }
-
- static TreeNode decrement( TreeNode node )
- {
- if( node.color == RED && node.parent.parent == node )
- {
- return node.right;
- }
- else if( node.left != NIL )
- {
- node = node.left;
-
- while( node.right != NIL )
- node = node.right;
-
- return node;
- }
- else
- {
- while( node == node.parent.left )
- node = node.parent;
-
- return node.parent;
- }
- }
-
- TreeNode minimum( TreeNode node )
- {
- if( node == NIL )
- {
- return myHeader;
- }
- else
- {
- while( node.left != NIL )
- node = node.left;
-
- return node;
- }
- }
-
- TreeNode maximum( TreeNode node )
- {
- if( node == NIL )
- {
- return myHeader;
- }
- else
- {
- while( node.right != NIL )
- node = node.right;
-
- return node;
- }
- }
-
- void rotateLeft( TreeNode x )
- {
- TreeNode y = x.right;
- x.right = y.left;
-
- if( y.left != NIL )
- y.left.parent = x;
-
- y.parent = x.parent;
-
- if( x == myHeader.parent )
- myHeader.parent = y;
- else if( x == x.parent.left )
- x.parent.left = y;
- else
- x.parent.right = y;
-
- y.left = x;
- x.parent = y;
- }
-
- void rotateRight( TreeNode x )
- {
- TreeNode y = x.left;
- x.left = y.right;
-
- if( y.right != NIL )
- y.right.parent = x;
-
- y.parent = x.parent;
-
- if( x == myHeader.parent )
- myHeader.parent = y;
- else if( x == x.parent.right )
- x.parent.right = y;
- else
- x.parent.left = y;
-
- y.right = x;
- x.parent = y;
- }
-
- void insert( boolean insertToLeft, TreeNode x, TreeNode y, TreeNode z )
- {
- if( insertToLeft )
- {
- y.left = z;
-
- if( y == myHeader )
- {
- myHeader.parent = z;
- myHeader.right = z;
- }
- else if( y == myHeader.left )
- {
- myHeader.left = z;
- }
- }
- else
- {
- y.right = z;
-
- if( y == myHeader.right )
- myHeader.right = z;
- }
-
- z.parent = y;
- z.left = NIL;
- z.right = NIL;
- x = z;
- x.color = RED;
-
- while( x != myHeader.parent && x.parent.color == RED )
- if( x.parent == x.parent.parent.left )
- {
- y = x.parent.parent.right;
-
- if( y.color == RED )
- {
- x.parent.color = BLACK;
- y.color = BLACK;
- x.parent.parent.color = RED;
- x = x.parent.parent;
- }
- else
- {
- if( x == x.parent.right )
- {
- x = x.parent;
- rotateLeft( x );
- }
-
- x.parent.color = BLACK;
- x.parent.parent.color = RED;
- rotateRight( x.parent.parent );
- }
- }
- else
- {
- y = x.parent.parent.left;
-
- if( y.color == RED )
- {
- x.parent.color = BLACK;
- y.color = BLACK;
- x.parent.parent.color = RED;
- x = x.parent.parent;
- }
- else
- {
- if( x == x.parent.left )
- {
- x = x.parent;
- rotateRight( x );
- }
-
- x.parent.color = BLACK;
- x.parent.parent.color = RED;
- rotateLeft( x.parent.parent );
- }
- }
-
- myHeader.parent.color = BLACK;
- }
-
- TreeNode remove( TreeNode z )
- {
- TreeNode y = z;
- TreeNode x;
-
- if( y.left == NIL )
- {
- x = y.right;
- }
- else if( y.right == NIL )
- {
- x = y.left;
- }
- else
- {
- y = y.right;
-
- while( y.left != NIL )
- y = y.left;
-
- x = y.right;
- }
-
- if( y != z )
- {
- z.left.parent = y;
- y.left = z.left;
-
- if( y != z.right )
- {
- x.parent = y.parent;
- y.parent.left = x;
- y.right = z.right;
- z.right.parent = y;
- }
- else
- {
- x.parent = y;
- }
-
- if( myHeader.parent == z )
- myHeader.parent = y;
- else if( z.parent.left == z )
- z.parent.left = y;
- else
- z.parent.right = y;
-
- y.parent = z.parent;
-
- // Swap color of y and z.
- int tmp = y.color;
- y.color = z.color;
- z.color = tmp;
-
- y = z;
- }
- else
- {
- x.parent = y.parent;
-
- if( myHeader.parent == z )
- myHeader.parent = x;
- else if( z.parent.left == z )
- z.parent.left = x;
- else
- z.parent.right = x;
-
- if( myHeader.left == z )
- if( z.right == NIL )
- myHeader.left = z.parent;
- else
- myHeader.left = minimum( x );
-
- if( myHeader.right == z )
- if( z.left == NIL )
- myHeader.right = z.parent;
- else
- myHeader.right = maximum( x );
- }
-
- if( y.color != RED )
- {
- while( x != myHeader.parent && x.color == BLACK )
- if( x == x.parent.left )
- {
- TreeNode w = x.parent.right;
-
- if( w.color == RED )
- {
- w.color = BLACK;
- x.parent.color = RED;
- rotateLeft( x.parent );
- w = x.parent.right;
- }
-
- if( w.left.color == BLACK && w.right.color == BLACK )
- {
- w.color = RED;
- x = x.parent;
- }
- else
- {
- if( w.right.color == BLACK )
- {
- w.left.color = BLACK;
- w.color = RED;
- rotateRight( w );
- w = x.parent.right;
- }
-
- w.color = x.parent.color;
- x.parent.color = BLACK;
- w.right.color = BLACK;
- rotateLeft( x.parent );
- break;
- }
- }
- else
- {
- TreeNode w = x.parent.left;
-
- if( w.color == RED )
- {
- w.color = BLACK;
- x.parent.color = RED;
- rotateRight( x.parent );
- w = x.parent.left;
- }
-
- if( w.right.color == BLACK && w.left.color == BLACK )
- {
- w.color = RED;
- x = x.parent;
- }
- else
- {
- if( w.left.color == BLACK )
- {
- w.right.color = BLACK;
- w.color = RED;
- rotateLeft( w );
- w = x.parent.left;
- }
-
- w.color = x.parent.color;
- x.parent.color = BLACK;
- w.left.color = BLACK;
- rotateRight( x.parent );
- break;
- }
- }
-
- x.color = BLACK;
- }
-
- --size;
- return y;
- }
- }
-
-