Difference between revisions of "CSC212 IntBST.java: A Non-Generic BST Implementation"

From dftwiki3
Jump to: navigation, search
(Created page with "--~~~~ ---- <br /> <source lang="java"> * * IntBST.java * @author D. Thiebaut, adapted from Drozdek's textbook. * Basic implementation of a Binary-Search Tree.: impor...")
 
Line 3: Line 3:
 
<br />
 
<br />
 
<source lang="java">
 
<source lang="java">
 +
 
/**
 
/**
 
  * IntBST.java
 
  * IntBST.java
  * @author D. Thiebaut, adapted from Drozdek's textbook.
+
  * @author D. Thiebaut
  * Basic implementation of a Binary-Search Tree.
+
* All material taken from, or adapted from Drozdek's
 +
* Data Structures and Algorithms in Java.
 +
  *  
 
  */
 
  */
 
 
import java.util.LinkedList;
 
import java.util.LinkedList;
 
import java.util.List;
 
import java.util.List;
 
import java.util.Queue;
 
import java.util.Queue;
  
 +
/**
 +
* A class implementing a BST node, with an integer key,
 +
* and a left and right pointer.
 +
* @author thiebaut
 +
*
 +
*/
 
class IntBSTNode {
 
class IntBSTNode {
   
+
    public int key;
+
public int key;
    public IntBSTNode left, right;
+
public IntBSTNode left, right;
    IntBSTNode( int el, IntBSTNode l, IntBSTNode r ) {
+
IntBSTNode( int el, IntBSTNode l, IntBSTNode r ) {
        key = el;
+
key = el;
        left = l;
+
left = l;
        right = r;
+
right = r;
    }
+
}
   
+
    IntBSTNode( int el ) {
+
IntBSTNode( int el ) {
        this( el, null, null );
+
this( el, null, null );
    }
+
}
 
}
 
}
  
 +
/**
 +
* The tree class.  Implements most useful methods.
 +
* @author thiebaut
 +
*
 +
*/
 
public class IntBST {
 
public class IntBST {
    protected IntBSTNode root;
+
protected IntBSTNode root;
   
+
    IntBST( ) {
+
/**
        root = null;
+
* constructor creates an empty tree.
    }
+
*/
    protected void setRoot( IntBSTNode p ) { root = p; }
+
IntBST( ) {
   
+
root = null;
    protected void debugVisit() {
+
}
        debugVisit( root );
+
    }
+
protected void setRoot( IntBSTNode p ) {  
   
+
root = p;  
    protected void debugVisit( IntBSTNode p ) {
+
}
        if ( p==null ) return;
+
        String leftString="has no left child", rightString = "has no right child";
+
public void clear() {
        if ( p.left != null) leftString = "has " + p.left.key + " as left child";
+
root = null;
        if ( p.right != null) rightString = "has " + p.right.key + " as right child";
+
}
        System.out.println( "Node " + p.key + ", " + leftString + ", and " + rightString );
 
        debugVisit( p.left );
 
        debugVisit( p.right );
 
    }
 
   
 
    public IntBSTNode search( int el ) {
 
        IntBSTNode p = root;
 
        while ( p != null ) {
 
            if ( el == p.key )
 
                return p;
 
            if ( el < p.key )
 
                p = p.left;
 
            else
 
                p = p.right;
 
        }
 
        return null;
 
    }
 
   
 
    public IntBSTNode recSearch( int el ) {
 
        return recSearch( root, el );
 
    }
 
   
 
    private IntBSTNode recSearch( IntBSTNode p, int el ) {
 
        if ( p==null )
 
            return null;
 
        if ( el == p.key )
 
            return p;
 
        if ( el < p.key )
 
            return recSearch( p.left, el );
 
        else
 
            return recSearch( p.right, el );
 
    }
 
   
 
   
 
    public void inOrderVisit() {
 
        inOrderVisit( root );
 
        System.out.println();
 
    }
 
    private void inOrderVisit( IntBSTNode p ) {
 
        if ( p==null )
 
            return;
 
        inOrderVisit( p.left );
 
        System.out.print( p.key + " ");
 
        inOrderVisit( p.right );
 
    }
 
   
 
    public void preOrderVisit() {
 
        preOrderVisit( root );
 
        System.out.println();
 
    }
 
    private void preOrderVisit( IntBSTNode p ) {
 
        if ( p==null )
 
            return;
 
        System.out.print( p.key + " ");
 
        preOrderVisit( p.left );
 
        preOrderVisit( p.right );
 
    }
 
   
 
    public void postOrderVisit() {
 
        postOrderVisit( root );
 
        System.out.println();
 
    }
 
    private void postOrderVisit( IntBSTNode p ) {
 
        if ( p==null )
 
            return;
 
        postOrderVisit( p.left );
 
        postOrderVisit( p.right );
 
        System.out.print( p.key + " ");
 
    }
 
   
 
   
 
    public void breadthFirst() {
 
        IntBSTNode p = root;
 
        Queue<IntBSTNode> queue = new LinkedList<IntBSTNode>();
 
 
 
        if ( p == null )  
+
/**
            return;
+
* Just use for debugging...  Recursively visits the tree
 +
* and display information about what it finds.
 +
*/
 +
protected void debugVisit() {
 +
debugVisit( root );
 +
}
 +
 +
protected void debugVisit( IntBSTNode p ) {
 +
if ( p==null ) return;
 +
String leftString="has no left child", rightString = "has no right child";
 +
if ( p.left != null) leftString = "has " + p.left.key + " as left child";
 +
if ( p.right != null) rightString = "has " + p.right.key + " as right child";
 +
System.out.println( "Node " + p.key + ", " + leftString + ", and " + rightString );
 +
debugVisit( p.left );
 +
debugVisit( p.right );
 +
}
 +
 +
/**
 +
* Iteratively searches for an element in the tree.  Returns the node
 +
* containing the element if found, or null otherwise.
 +
* @param el
 +
* @return
 +
*/
 +
public IntBSTNode search( int el ) {
 +
IntBSTNode p = root;
 +
while ( p != null ) {
 +
if ( el == p.key )
 +
return p;
 +
if ( el < p.key )
 +
p = p.left;
 +
else
 +
p = p.right;
 +
}
 +
return null;
 +
}
 +
 
 +
/**
 +
* recursively searches for an element in the tree.  Returns the
 +
* node containing the element, or null if not found.
 +
* @param el
 +
* @return
 +
*/
 +
public IntBSTNode recSearch( int el ) {
 +
return recSearch( root, el );
 +
}
 
 
        queue.add( p );
+
private IntBSTNode recSearch( IntBSTNode p, int el ) {  
        while ( ! queue.isEmpty() ){
+
if ( p==null )
            p = queue.poll();
+
return null;
            //--- do some work with the key.  Here we just print it...
+
if ( el == p.key )  
            System.out.print( p.key + " " );
+
return p;
            if ( p.left != null ) queue.add( p.left );
+
if ( el < p.key )
            if ( p.right != null ) queue.add( p.right );
+
return recSearch( p.left, el );
        }
+
else
    }
+
return recSearch( p.right, el );
   
+
}
   
 
    public void insert( int el ) { }
 
    public void delete( int el ) { }
 
    public void balance() { }
 
   
 
    static public void main( String[] args ) {
 
        IntBST tree = new IntBST();
 
        //--- create a tree (not the best way...)
 
        //                8
 
        //        3            10
 
        //      1      6            14
 
        //          4    7        13
 
        //
 
        IntBSTNode q, p = new IntBSTNode( 4 );
 
        p = new IntBSTNode( 6, p, new IntBSTNode( 7 ) );
 
        p = new IntBSTNode( 3, new IntBSTNode( 1 ), p );
 
       
 
        q = new IntBSTNode( 13 );
 
        q = new IntBSTNode( 14, q, null );
 
        q = new IntBSTNode( 10, null, q );
 
        tree.setRoot( new IntBSTNode( 8, p, q ) );
 
       
 
        tree.debugVisit( );
 
  
        // search the tree for various keys, stored in array keys...       
+
        int[] keys = new int[] { 8, 3, 6, 13, 20 };
+
/**
       
+
* Traveral methods
        for ( int i=0; i<keys.length; i++  ) {
+
* inOrderVisit
            int key = keys[i];
+
* preOrderVisit
            IntBSTNode r = tree.search( key );
+
* postOrderVisit
            if ( r== null )  
+
*/
                System.out.println( key + " not found" );
+
public void inOrderVisit() {
            else
+
inOrderVisit( root );
                System.out.println( key + " found!  Hourray!" );
+
System.out.println();
           
+
}
            r = tree.recSearch( key );
+
            if ( r== null )  
+
private void inOrderVisit( IntBSTNode p ) {
                System.out.println( key + " not found" );
+
if ( p==null )
            else
+
return;
                System.out.println( key + " found!  Hourray!" );
+
inOrderVisit( p.left );
        }
+
System.out.print( p.key + " ");
 +
inOrderVisit( p.right );
 +
}
 +
 +
public void preOrderVisit() {
 +
preOrderVisit( root );
 +
System.out.println();
 +
}
 +
private void preOrderVisit( IntBSTNode p ) {
 +
if ( p==null )
 +
return;
 +
System.out.print( p.key + " ");
 +
preOrderVisit( p.left );
 +
preOrderVisit( p.right );
 +
}
  
        // visit the tree, different ways...
+
public void postOrderVisit() {
        System.out.println( "Breadth-First" );
+
postOrderVisit( root );
        tree.breadthFirst();
+
System.out.println();
 +
}
 +
private void postOrderVisit( IntBSTNode p ) {
 +
if ( p==null )
 +
return;
 +
postOrderVisit( p.left );
 +
postOrderVisit( p.right );
 +
System.out.print( p.key + " ");
 +
}
  
        System.out.println( "In-Order Visit" );
+
/**
        tree.inOrderVisit();
+
* visits the tree breadth-first.  Display the key in all
        System.out.println( "Pre-Order Visit" );
+
* the nodes, in breadth-first order.
        tree.preOrderVisit();
+
*/
        System.out.println( "Post-Order Visit" );
+
public void breadthFirst() {
         tree.postOrderVisit();
+
IntBSTNode p = root;
 +
Queue<IntBSTNode> queue = new LinkedList<IntBSTNode>();
 +
 +
if ( p == null )
 +
return;
 +
 +
queue.add( p );
 +
while ( ! queue.isEmpty() ){
 +
p = queue.poll();
 +
//--- do some work with the key.  Here we just print it...
 +
System.out.print( p.key + " " );
 +
if ( p.left != null ) queue.add( p.left );
 +
if ( p.right != null ) queue.add( p.right );
 +
}
 +
}
 +
 +
/**
 +
* Inserts an element in the tree.  We assume that the element
 +
* is not already there.
 +
* @param el
 +
*/
 +
public void insert( int el ) {
 +
// is the tree empty?  if so, create 1 node
 +
if ( root==null ) {
 +
root = new IntBSTNode( el );
 +
return;
 +
}
 +
 +
// go down to the leaf that will be the parent
 +
// of the new node
 +
IntBSTNode p = root, prev = null;
 +
while ( p != null ) {
 +
prev = p;
 +
if ( p.key < el )
 +
p = p.right;
 +
else
 +
p = p.left;
 +
}
 +
 +
// add element as new leaf of prev's node
 +
if ( el < prev.key )
 +
prev.left = new IntBSTNode( el );
 +
else
 +
prev.right = new IntBSTNode( el );
 +
}
 +
 +
/**
 +
* Delete element by merging. Finds the element, then the largest
 +
* of its left-subtree, and attaches the right-subtree of the node to
 +
* delete to this largest element.
 +
* @param el: the key we want to remove.
 +
*/
 +
public void delete( int el ) {
 +
IntBSTNode tmp, node, p=root, prev = null;
 +
 +
if ( root == null ) {
 +
System.out.println( "Trying to delete from an empty tree" );
 +
return;
 +
}
 +
 +
// find the node containing el
 +
while ( p!=null && p.key != el ) {
 +
prev = p;
 +
if (p.key < el )  
 +
p = p.right;
 +
else
 +
p = p.left;
 +
}
 +
 +
if ( p==null ) {
 +
System.out.println( "Key " + el + " not in tree" );
 +
return;
 +
}
 +
 +
// we found the element.  p is pointing to it.  prev is pointing to
 +
// parent (or is null if el is in root).
 +
node = p;
 +
 +
// no right sub-tree? 
 +
if ( node.right == null ) {
 +
// yes, then pick the left subtree
 +
node = node.left;
 +
}
 +
else if ( node.left == null ) {
 +
// yes, then pick the right subtree
 +
node = node.right;
 +
}
 +
else {
 +
// two existing subtrees.
 +
// go to left subtree
 +
tmp = node.left;
 +
 +
// and find the right-most node that doesn't have a right child.
 +
while ( tmp.right != null )
 +
tmp = tmp.right;
 +
 +
// tmp points to right-most node (blue node)
 +
 +
// attach right subtree of node we're deleting (yellow node)
 +
// to right most node (blue node)
 +
tmp.right = node.right;
 +
 +
node = node.left;
 +
}
 +
 +
if ( p==root )
 +
root = node;
 +
else if ( prev.left == p )
 +
prev.left = node;
 +
else
 +
prev.right = node;
 +
}
 +
 +
public void balance() { }
 +
 +
static public void main( String[] args ) {
 +
IntBST2 tree = new IntBST2();
 +
 +
        // create a new tree by using insert()
 +
         int[] keys = new int[] { 8, 3, 10, 1, 6, 14, 4, 7, 13 };
 +
 +
        for ( int i=0; i< keys.length; i++ )
 +
        tree.insert( keys[i] );
 
          
 
          
    }
+
        tree.breadthFirst();
 +
}
 
}
 
}
 +
  
 
</source>
 
</source>

Revision as of 16:32, 29 October 2014

--D. Thiebaut (talk) 19:59, 28 October 2014 (EDT)



/**
 * IntBST.java
 * @author D. Thiebaut
 * All material taken from, or adapted from Drozdek's
 * Data Structures and Algorithms in Java.
 * 
 */
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * A class implementing a BST node, with an integer key,
 * and a left and right pointer.
 * @author thiebaut
 *
 */
class IntBSTNode {
	
	public int key;
	public IntBSTNode left, right;
	IntBSTNode( int el, IntBSTNode l, IntBSTNode r ) {
		key = el;
		left = l;
		right = r;
	}
	
	IntBSTNode( int el ) {
		this( el, null, null );
	}
}

/**
 * The tree class.  Implements most useful methods.
 * @author thiebaut
 *
 */
public class IntBST {
	protected IntBSTNode root;
	
	/**
	 * constructor creates an empty tree.
	 */
	IntBST( ) {
		root = null;
	}
	
	protected void setRoot( IntBSTNode p ) { 
		root = p; 
	}
	
	public void clear() {
		root = null;
	}
	
	/**
	 * Just use for debugging...  Recursively visits the tree
	 * and display information about what it finds.
	 */
	protected void debugVisit() {
		debugVisit( root );
	}
		
	protected void debugVisit( IntBSTNode p ) { 
		if ( p==null ) return;
		String leftString="has no left child", rightString = "has no right child";
		if ( p.left != null) leftString = "has " + p.left.key + " as left child";
		if ( p.right != null) rightString = "has " + p.right.key + " as right child";
		System.out.println( "Node " + p.key + ", " + leftString + ", and " + rightString );
		debugVisit( p.left );
		debugVisit( p.right );
	}
	
	/**
	 * Iteratively searches for an element in the tree.  Returns the node
	 * containing the element if found, or null otherwise.
	 * @param el
	 * @return
	 */
	public IntBSTNode search( int el ) { 
		IntBSTNode p = root;
		while ( p != null ) {
			if ( el == p.key ) 
				return p;
			if ( el < p.key )
				p = p.left;
			else 
				p = p.right;
		}
		return null; 		
	}

	/**
	 * recursively searches for an element in the tree.  Returns the
	 * node containing the element, or null if not found.
	 * @param el
	 * @return
	 */
	public IntBSTNode recSearch( int el ) { 
		return recSearch( root, el );
	}
	
	private IntBSTNode recSearch( IntBSTNode p, int el ) { 
		if ( p==null )
			return null;
		if ( el == p.key ) 
			return p;
		if ( el < p.key )
			return recSearch( p.left, el );
		else	
			return recSearch( p.right, el );
	}

	
	/**
	 * Traveral methods
	 * inOrderVisit
	 * preOrderVisit
	 * postOrderVisit
	 */
	public void inOrderVisit() {
		inOrderVisit( root );
		System.out.println();
	}
	
	private void inOrderVisit( IntBSTNode p ) {
		if ( p==null )
			return;
		inOrderVisit( p.left );
		System.out.print( p.key + " ");
		inOrderVisit( p.right );
	}
	
	public void preOrderVisit() {
		preOrderVisit( root );
		System.out.println();
	}
	private void preOrderVisit( IntBSTNode p ) {
		if ( p==null )
			return;
		System.out.print( p.key + " ");
		preOrderVisit( p.left );
		preOrderVisit( p.right );
	}

	public void postOrderVisit() {
		postOrderVisit( root );
		System.out.println();
	}
	private void postOrderVisit( IntBSTNode p ) {
		if ( p==null )
			return;
		postOrderVisit( p.left );
		postOrderVisit( p.right );
		System.out.print( p.key + " ");
	}

	/**
	 * visits the tree breadth-first.  Display the key in all
	 * the nodes, in breadth-first order.
	 */
	public void breadthFirst() {
		IntBSTNode p = root;
		Queue<IntBSTNode> queue = new LinkedList<IntBSTNode>();
		
		if ( p == null ) 
			return;
		
		queue.add( p );
		while ( ! queue.isEmpty() ){
			p = queue.poll();
			//--- do some work with the key.  Here we just print it...
			System.out.print( p.key + " " );
			if ( p.left != null ) queue.add( p.left );
			if ( p.right != null ) queue.add( p.right );
		}
	}
	
	/**
	 * Inserts an element in the tree.  We assume that the element
	 * is not already there.
	 * @param el
	 */
	public void insert( int el ) {		
		// is the tree empty?  if so, create 1 node
		if ( root==null ) {
			root = new IntBSTNode( el );
			return;
		}
		
		// go down to the leaf that will be the parent
		// of the new node
		IntBSTNode p = root, prev = null;
		while ( p != null ) {
			prev = p;
			if ( p.key < el ) 
				p = p.right;
			else
				p = p.left;
		}
		
		// add element as new leaf of prev's node
		if ( el < prev.key )
			prev.left = new IntBSTNode( el );
		else
			prev.right = new IntBSTNode( el );
	}
	
	/**
	 * Delete element by merging.  Finds the element, then the largest 
	 * of its left-subtree, and attaches the right-subtree of the node to 
	 * delete to this largest element.
	 * @param el: the key we want to remove.
	 */
	public void delete( int el ) { 
		IntBSTNode tmp, node, p=root, prev = null;
		
		if ( root == null ) { 
			System.out.println( "Trying to delete from an empty tree" );
			return;
		}
		
		// find the node containing el
		while ( p!=null && p.key != el ) {
			prev = p;
			if (p.key < el ) 
				p = p.right;
			else
				p = p.left;
		}
		
		if ( p==null ) {
			System.out.println( "Key " + el + " not in tree" );
			return;
		}
		
		// we found the element.  p is pointing to it.  prev is pointing to 
		// parent (or is null if el is in root).
		node = p;
		
		// no right sub-tree?  
		if ( node.right == null ) {
			// yes, then pick the left subtree
			node = node.left;
		}
		else if ( node.left == null ) {
			// yes, then pick the right subtree
			node = node.right;
		}
		else {
			// two existing subtrees.
			// go to left subtree
			tmp = node.left; 
			
			// and find the right-most node that doesn't have a right child.
			while ( tmp.right != null ) 
				tmp = tmp.right;
			
			// tmp points to right-most node (blue node)
			
			// attach right subtree of node we're deleting (yellow node)
			// to right most node (blue node)
			tmp.right = node.right;
			
			node = node.left;
		}
		
		if ( p==root ) 
			root = node;
		else if ( prev.left == p )
			prev.left = node;
		else
			prev.right = node;
	}
	
	public void balance() { }
	
	static public void main( String[] args ) {
		IntBST2 tree = new IntBST2();
		
        // create a new tree by using insert()
        int[] keys = new int[] { 8, 3, 10, 1, 6, 14, 4, 7, 13 };
 
        for ( int i=0; i< keys.length; i++ ) 
        	tree.insert( keys[i] );	
        
        tree.breadthFirst();
	}
}