CS 535 Object-Oriented Programming & Design Spring Semester, 1999 Distribute System Intelligence: A Tree Example |
||
---|---|---|
© 1999, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 27-Apr-99 |
Distribute System Intelligence
A Tree Example
Problem:
class DumbNode { protected DumbNode left = null; protected DumbNode right = null; protected int key; protected Object value; public DumbNode( int key, Object value ) { this.key = key; this.value = value; } }
package sdsu.trees; import java.util.*; public class SmartTree { protected DumbNode root = null; // Methods shown later }
SmartTree MethodsHelper Function /** * If keyToFind is in the tree rooted at startNode, then return node * containing keyToFind. * Otherwise return the node that would be parent of a node containing * keyToFind. */ protected DumbNode getNode( int keyToFind, DumbNode startNode ) { DumbNode current = startNode; DumbNode parent = null; DumbNode nextNode = null; while ( current != null ) { if ( keyToFind < current.key ) nextNode = current.left; else if (keyToFind > current.key ) nextNode = current.right; else return current; parent = current; current = nextNode; } // Key not found, return parent; }
SmartTree Methodsget
/** * Gets the object associated with the specified key in the tree. * If key is not in tree return null */ public Object get( int key ) { if ( root == null ) return null; DumbNode foundNode = getNode( key, root ); if ( foundNode.key == key ) return foundNode.value; else return null; }
SmartTree Methodsput
/** * Puts the specified element into the tree, using the specified key. */ public Object put( int key, Object value ) { if ( root == null ) { root = new DumbNode( key, value ); return null; } DumbNode foundNode = getNode( key, root ); if ( foundNode.key == key ) { // Replace existing value Object oldValue = foundNode.value; foundNode.value = value; return oldValue; } else //Key not in tree, add new node { if ( key > foundNode.key ) foundNode.right = new DumbNode( key, value ); else foundNode.left = new DumbNode( key, value ); return null; } }
SmartTree MethodsPreorder Traversal 1) Print "(" then Visit left subtree
2) Print node
3) Visit right subtree, then print ")"
Applying rule we get:
( left subtree 5 right subtree ) ( (3) 5 ( left subtree 8 right subtree ) ) ( (3) 5 ( (6) 8 (9) ) )
SmartTree MethodstoString() Helper Class
Need to store path of nodes visited on a stack with which visit we are on: first, second or third
public class TraversalInfo { public DumbNode node; public int visitNumber; public TraversalInfo( DumbNode nodeTraversed, int visitNumber ) { node = nodeTraversed; this.visitNumber = visitNumber; } }Constants for toString()
private final static int FIRST = 1; private final static int SECOND = 2; private final static int THIRD = 3;
SmartTree MethodstoString(): Simple Algorithm public String toString() { StringBuffer treeString = new StringBuffer(); TraversalInfo currentLocation; Stack visited = new Stack(); visited.push( new TraversalInfo( root, FIRST ) ); while ( visited.empty() != true ) { currentLocation = (TraversalInfo) visited.pop(); switch ( currentLocation.visitNumber ) { case FIRST: treeString.append( "(" ); firstVisit( visited, currentLocation ); break; case SECOND: treeString.append( currentLocation.node.key ); secondVisit( visited, currentLocation ); break; case THIRD: treeString.append( ")" ); break; } } return treeString.toString(); }
SmartTree MethodstoString(): continued protected void firstVisit( Stack visited, TraversalInfo currentLocation ) { DumbNode nextnode; currentLocation.visitNumber = SECOND; visited.push( currentLocation ); if ( currentLocation.node.left != null ) { nextnode = currentLocation.node.left; visited.push( new TraversalInfo( nextnode, FIRST ) ); } } protected void secondVisit( Stack visited, TraversalInfo currentLocation ) { DumbNode nextnode; currentLocation.visitNumber = THIRD; visited.push( currentLocation ); if ( currentLocation.node.right != null ) { nextnode = currentLocation.node.right; visited.push( new TraversalInfo( nextnode, FIRST ) ); } }
Solution 2 DumbTree, BSTNode
1) Let the nodes do some work 2) Add some nil leaves to eliminate some cases
Class StructureInheritance
Runtime Structure
DumbTree
package sdsu.trees; public class DumbTree { protected TreeNode root = null; public Object get( int key ) { if ( root == null ) return null; return root.getNode( key ).value(); } public Object put( int key, Object value ) { if ( root == null ) { root = new BSTNode( key, value ); return null; } return root.getNode( key ).put( key, value ); } public String toString() { return root.toString(); } }
TreeNode
abstract class TreeNode { /** * Puts the specified key & value in this node */ abstract public Object put( int key, Object value ); /** * Return the value of the TreeNode */ abstract public Object value(); /** * If keyToFind is in the subtree rooted at this node, then return * node containing keyToFind. * Otherwise return the NilLeaf that should contain keyToFind */ abstract public TreeNode getNode( int key ); /** * Return an ascii representation of tree rooted at this node */ abstract public String toString(); }Comments
There is no common code or methods between BSTNode and NilLeaf
TreeNode could be either an interface or an abstract class
BSTNode
class BSTNode extends TreeNode { protected TreeNode left; protected TreeNode right; protected int key; protected Object value; public BSTNode( int key, Object value ) { this.key = key; this.value = value; left = new NilLeaf( this ); right = new NilLeaf( this ); } /** * Return the value of the TreeNode */ public Object value() { return value; } /** * Return an ascii representation of tree rooted at this node */ public String toString() { return "(" + left.toString() + key + right.toString() + ")"; }
BSTNode Continued public Object put( int keyToAdd, Object valueToAdd ) { Object oldValue = value; value = valueToAdd; return oldValue; } /** * If keyToFind is in the subtree rooted at this node, then return * node containing keyToFind. * Otherwise return the NilLeaf that should contain keyToFind */ public TreeNode getNode( int keyToFind ) { if ( keyToFind < key ) return left.getNode( keyToFind ); else if ( keyToFind > key ) return right.getNode( keyToFind ); else return this; } /** * Puts indicated key and value in proper child of this node */ protected void putAsChild( int keyToAdd, Object valueToAdd ) { if ( keyToAdd < key ) left = new BSTNode( keyToAdd, valueToAdd ); else if ( keyToAdd > key ) right = new BSTNode( keyToAdd, valueToAdd ); } }
NilLeaf
class NilLeaf extends TreeNode { protected BSTNode parent; public NilLeaf( BSTNode parent ) { this.parent = parent; } public Object put( int key, Object value ) { parent.putAsChild( key, value ); return null; } public Object value() { return null; } public TreeNode getNode( int key ) { return this; } public String toString() { return ""; } }
How Does this Work?
DumbTree example = new DumbTree(); example.put( 5, null ); example.put( 3, null ); example.put( 8, null ); // Now add a 1
example.put( 1, null ); // In DumbTree's put( 1, null ) method does: return root.getNode( 1 ).put( 1, null ); // in BSTNode with key 5 method getNode( 1 ) does: if ( 1 < 5 ) return left.getNode( 1 ); else if ( 1 > 5 ) return right.getNode( 1 ); else return this;
Example Continued
// in BSTNode with key 3 method getNode( 1 ) does: if ( 1 < 3 ) return left.getNode( 1 ); else if ( 1 > 3 )
// in NilNode method getNode( 1 ) does:
return this;
// in BSTNode with key 3 method getNode( 1 ) does: if ( 1 < 3 ) return left.getNode( 1 );
Example Continued
// in BSTNode with key 5 method getNode( 1 ) does: if ( 1 < 5 ) return left.getNode( 1 );
// In DumbTree's put( 1, null ) method does: return root.getNode( 1 ).put( 1, null );
// in NilNode method put( 1, null ) does: parent.putAsChild( 1, null ); return null;
Example Continued // in BSTNode with key 3 method putAsChild( 1, null ) does: if ( 1 < 3 ) left = new BSTNode( 1, null ); else if ( 1 > 3 )
// in NilNode method put( 1, null ) does: parent.putAsChild( 1, null ); return null;
// In DumbTree's put( 1, null ) method does: return root.getNode( 1 ).put( 1, null );
Comparison
Metric | SmartTree | DumbTree |
LOC | 60 | 36 |
Number of classes | 3 | 4 |
Number of methods | 6[1] | 18[2] |
LOC/method | 10 | 2 |
Issue Avoid Case (and if) Statements
Implementation that avoids if statements by sending a message to an object
NilLeaf returns a null string;
public String toString() { return "(" + left.toString() + key + right.toString() + ")"; }
Implementation that uses if statements
public String toString() { String treeRepresentation; treeRepresentation = "("; if ( left != null ) treeRepresentation = treeRepresentation + left.toString(); treeRepresentation = treeRepresentation + left.toString(); if ( right != null ) treeRepresentation = treeRepresentation + right.toString(); treeRepresentation = treeRepresentation + ")"; return treeRepresentation; }
Issues: Performance
Have you lost your mind?
DumbTree is slower than SmartTreePerformance Test
Insert ints from 1 to N into each tree
Look up each int once
Times are measured on a PowerMac 7100/80
Times are in milliseconds
Timing Results
N -> | 400 | 800 | 1600 |
SmartTree create | 264 | 1064 | 4342 |
DumbTree create | 314 | 1290 | 5681 |
SmartTree find all | 261 | 1049 | 4197 |
DumbTree find all | 272 | 1193 | 5370 |
More Timing Results
N -> | 400 | 800 | 1600 |
SmartTree create | 264 | 1064 | 4342 |
DumbTree create | 314 | 1290 | 5681 |
DumbAVLTree create | 46 | 94 | 196 |
Hashtable create | 42 | 82 | 165 |
Opt. Hashtable create | 25 | 57 | 102 |
SmartTree find all | 261 | 1049 | 4197 |
DumbTree find all | 272 | 1193 | 5370 |
DumbAVLTree find all | 11 | 23 | 50 |
Hashtable find all | 30 | 61 | 127 |
Opt. Hashtable find all | 14 | 27 | 54 |
[1]Originally firstVisit and second visit methods did not exist. They were added just to make each method fit on one slide. Hence I did not count them as methods for this comparison.
[2]This includes the abstract class
Copyright ©, All rights reserved.
1999 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous    visitors since 27-Apr-99    Next