// Deterministic skip list class class // // CONSTRUCTION: with INFINITY object that is used as a sentinel. // // ******************PUBLIC OPERATIONS********************* // void insert( x ) --> Insert x // void remove( x ) --> Remove x (unimplemented) // bool contains( x ) --> Return true if x is present // Comparable findMin( ) --> Return smallest item // Comparable findMax( ) --> Return largest item // boolean isEmpty( ) --> Return true if empty; else false // void makeEmpty( ) --> Remove all items // ******************ERRORS******************************** // Throws UnderflowException as appropriate /** * Implements a deterministic skip list. * Note that all "matching" is based on the compareTo method. * @author Mark Allen Weiss */ public class DSL> { /** * Construct the DSL. * @param inf the largest Comparable. */ public DSL( AnyType inf ) { infinity = inf; bottom = new SkipNode( null ); bottom.right = bottom.down = bottom; tail = new SkipNode( infinity ); tail.right = tail; header = new SkipNode( infinity, tail, bottom ); } /** * Insert into the DSL. * @param x the item to insert. */ public void insert( AnyType x ) { SkipNode current = header; bottom.element = x; while( current != bottom ) { while( current.element.compareTo( x ) < 0 ) current = current.right; // If gap size is 3 or at bottom level and // must insert, then promote middle element if( current.down.right.right.element.compareTo( current.element ) < 0 ) { current.right = new SkipNode( current.element, current.right, current.down.right.right ); current.element = current.down.right.element; } else current = current.down; } // Raise height of DSL if necessary if( header.right != tail ) header = new SkipNode( infinity, tail, header ); } /** * Remove from the DSL. Unimplemented. * @param x the item to remove. */ public void remove( AnyType x ) { System.out.println( "Sorry, remove unimplemented" ); } /** * Find the smallest item in the DSL. * @return smallest item, or throw UnderflowException if empty. */ public AnyType findMin( ) { if( isEmpty( ) ) throw new UnderflowException( ); SkipNode current = header; while( current.down != bottom ) current = current.down; return current.element; } /** * Find the largest item in the DSL. * @return the largest item, or throw UnderflowException if empty. */ public AnyType findMax( ) { if( isEmpty( ) ) throw new UnderflowException( ); SkipNode current = header; for( ; ; ) if( current.right.right != tail ) current = current.right; else if( current.down != bottom ) current = current.down; else return current.element; } /** * Find an item in the DSL. * @param x the item to search for. * @return the true if not found. */ public boolean contains( AnyType x ) { SkipNode current = header; bottom.element = x; for( ; ; ) { int compareResult = x.compareTo( current.element ); if( compareResult < 0 ) current = current.down; else if( compareResult > 0 ) current = current.right; else return current != bottom; } } /** * Make the DSL logically empty. */ public void makeEmpty( ) { header.right = tail; header.down = bottom; } /** * Test if the DSL is logically empty. * @return true if empty, false otherwise. */ public boolean isEmpty( ) { return header.right == tail && header.down == bottom; } /** * Print the DSL. */ private void printList( ) { SkipNode current = header; while( current.down != bottom ) ; while( current.right != tail ) { System.out.println( current.element ); current = current.right; } } private static class SkipNode { // Constructors SkipNode( AnyType theElement ) { this( theElement, null, null ); } SkipNode( AnyType theElement, SkipNode rt, SkipNode dt ) { element = theElement; right = rt; down = dt; } AnyType element; // The data in the node SkipNode right; // Right link SkipNode down; // Down link } /** The DSL header. */ private SkipNode header; private AnyType infinity; private SkipNode bottom = null; private SkipNode tail = null; // Test program public static void main( String [ ] args ) { DSL t = new DSL( 100000000 ); final int NUMS = 400000; final int GAP = 37; System.out.println( "Checking... (no more output means success)" ); for( int i = GAP; i != 0; i = ( i + GAP ) % NUMS ) t.insert( i ); if( NUMS < 40 ) t.printList( ); if( t.findMin( ) != 1 || t.findMax( ) != NUMS - 1 ) System.out.println( "FindMin or FindMax error!" ); for( int i = 1; i < NUMS; i++ ) if( !t.contains( i ) ) System.out.println( "Find error1!" ); if( t.contains( 0 ) ) System.out.println( "Find error2!" ); if( t.contains( NUMS + 10 ) ) System.out.println( "Find error2!" ); } }