lab 108
This commit is contained in:
		
							parent
							
								
									d1948b0e58
								
							
						
					
					
						commit
						b1fe8d6ea1
					
				
					 17 changed files with 1121 additions and 0 deletions
				
			
		
							
								
								
									
										97
									
								
								Lab108-VenbergGE/src/Client.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								Lab108-VenbergGE/src/Client.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,97 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2021 Gabriel Venberg
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import javax.swing.JOptionPane;
 | 
			
		||||
import java.util.Scanner;
 | 
			
		||||
public class Client {
 | 
			
		||||
    public static void main(String[] args){
 | 
			
		||||
        String filePath = (String) JOptionPane.showInputDialog(null, "Enter the path of the file");
 | 
			
		||||
        File file = new File(filePath);
 | 
			
		||||
        try {
 | 
			
		||||
            Scanner fileContents = new Scanner(file);
 | 
			
		||||
            
 | 
			
		||||
            while(fileContents.hasNextLine()){
 | 
			
		||||
                
 | 
			
		||||
                String expression = fileContents.nextLine();
 | 
			
		||||
                System.out.println("input expression is: "+expression);
 | 
			
		||||
                try{
 | 
			
		||||
                    ArrayQueue postFix = ShuntingYard.shuntingYard(expression);
 | 
			
		||||
                    
 | 
			
		||||
                    //computing the result ahead of time to catch exceptions before the postfix is printed.
 | 
			
		||||
                    double result = ShuntingYard.evalPostfix(postFix);
 | 
			
		||||
                    
 | 
			
		||||
                    System.out.println("postfix is: ");
 | 
			
		||||
                    //non-destrutive printing
 | 
			
		||||
                    for(int i=0; i<postFix.size(); i++){
 | 
			
		||||
                        System.out.print(postFix.first().toString()+" ");
 | 
			
		||||
                        postFix.enqueue(postFix.dequeue());
 | 
			
		||||
                    }
 | 
			
		||||
                    System.out.println();
 | 
			
		||||
                    
 | 
			
		||||
                    System.out.println("expression evaluates to: "+result);
 | 
			
		||||
                    System.out.println();
 | 
			
		||||
                    
 | 
			
		||||
                    LinkedBinaryTree<String> expressionTree = ShuntingYard.convertToBinaryTree(postFix);
 | 
			
		||||
                    System.out.println("preorder of tree is:");
 | 
			
		||||
                    for(Position s:expressionTree.preorder()){
 | 
			
		||||
			System.out.print(s.getElement());
 | 
			
		||||
                    }
 | 
			
		||||
                    System.out.println();
 | 
			
		||||
                    
 | 
			
		||||
                    System.out.println("postorder of tree is:");
 | 
			
		||||
                    for(Position s:expressionTree.postorder()){
 | 
			
		||||
			System.out.print(s.getElement());
 | 
			
		||||
                    }
 | 
			
		||||
                    System.out.println();
 | 
			
		||||
                    
 | 
			
		||||
                    System.out.println("inorder of tree is:");
 | 
			
		||||
                    for(Position s:expressionTree.inorder()){
 | 
			
		||||
			System.out.print(s.getElement());
 | 
			
		||||
                    }
 | 
			
		||||
                    System.out.println();
 | 
			
		||||
                    
 | 
			
		||||
                    System.out.println("parenthasized expression is:");
 | 
			
		||||
                    eulerTourPrint(expressionTree, expressionTree.root());
 | 
			
		||||
                    System.out.println("\n\n");
 | 
			
		||||
                }
 | 
			
		||||
                catch(IllegalArgumentException ex){
 | 
			
		||||
                    System.out.println("invalid expression!");
 | 
			
		||||
                }
 | 
			
		||||
                catch(NullPointerException ex){
 | 
			
		||||
                    System.out.println("invalid expression!");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (FileNotFoundException ex) {
 | 
			
		||||
            JOptionPane.showMessageDialog(null, "file does not exist.");
 | 
			
		||||
            System.exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    	private static void eulerTourPrint(AbstractBinaryTree t, Position p){
 | 
			
		||||
		if(t.isInternal(p)){System.out.print('(');}
 | 
			
		||||
		if(t.left(p)!=null){eulerTourPrint(t, t.left(p));}
 | 
			
		||||
		System.out.print(p.getElement());
 | 
			
		||||
		if(t.right(p)!=null){eulerTourPrint(t, t.right(p));}
 | 
			
		||||
		if(t.isInternal(p)){System.out.print(')');}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
/*
 | 
			
		||||
 *  * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragments 8.7, 8.26, 8.22
 | 
			
		||||
 *\
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * an abstract base class providing some functionality of the binarytree interface
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractBinaryTree<E> extends AbstractTree<E> implements BinaryTree<E> {
 | 
			
		||||
	public Position<E> sibling(Position<E> p){
 | 
			
		||||
		Position<E> parent = parent(p);
 | 
			
		||||
		//p is root.
 | 
			
		||||
		if (parent == null){return null;}
 | 
			
		||||
		//p is left child, right child might be null.
 | 
			
		||||
		if (p==left(parent)){return right(parent);}
 | 
			
		||||
		//p is right child, left child might be null.
 | 
			
		||||
		else {return left(parent);}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**returns the number of children of Position p*/
 | 
			
		||||
	public int numChildren(Position<E> p){
 | 
			
		||||
		int count=0;
 | 
			
		||||
		if (left(p)!=null){count++;}
 | 
			
		||||
		if(right(p)!=null){count++;}
 | 
			
		||||
		return count;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**returns an iterable collection of Positions representing p's children.*/
 | 
			
		||||
	public Iterable<Position<E>> children(Position<E> p){
 | 
			
		||||
		//max capacity of 2
 | 
			
		||||
		List <Position<E>> snapshot=new ArrayList<>(2);
 | 
			
		||||
		//needed to modify this, as the arraylist we made in class needed an index
 | 
			
		||||
		if(left(p)!=null){snapshot.add(left(p));}
 | 
			
		||||
		if(right(p)!=null){snapshot.add(right(p));}
 | 
			
		||||
		// and our arraylist 
 | 
			
		||||
		return snapshot;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**adds positions of the subtree rooted at Position p to the given snapshot*/
 | 
			
		||||
	private void inorderSubtree(Position<E> p, List<Position<E>> snapshot){
 | 
			
		||||
		if(left(p)!=null){inorderSubtree(left(p), snapshot);}
 | 
			
		||||
		snapshot.add(p);
 | 
			
		||||
		if(right(p)!=null){inorderSubtree(right(p), snapshot);}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**returns an iterable collection of the positions of the tree, reported in inorder.*/
 | 
			
		||||
	public Iterable<Position<E>> inorder(){
 | 
			
		||||
		List<Position<E>> snapshot=new ArrayList<>();
 | 
			
		||||
		//fill snapshot recursively
 | 
			
		||||
		if(!isEmpty()){inorderSubtree(root(), snapshot);}
 | 
			
		||||
		return snapshot;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**Overrides positions to make inorder the default order for binary trees*/
 | 
			
		||||
	public Iterable<Position<E>> positions(){
 | 
			
		||||
		return inorder();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
			//nested ElementIterator class
 | 
			
		||||
		/**this class adapts the iteration produced by positions() to returns elements*/
 | 
			
		||||
		private class ElementIterator implements Iterator<E>{
 | 
			
		||||
			Iterator<Position<E>> posIterator=positions().iterator();
 | 
			
		||||
			public boolean hasNext(){return posIterator.hasNext();}
 | 
			
		||||
			//return element
 | 
			
		||||
			public E next(){return posIterator.next().getElement();}
 | 
			
		||||
			public void remove(){posIterator.remove();}
 | 
			
		||||
		}//end of nested ElementIterator class
 | 
			
		||||
		
 | 
			
		||||
		/**returns an iterator if the elements stored in the tree*/
 | 
			
		||||
		public Iterator<E> iterator(){return new ElementIterator();}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/AbstractTree.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/AbstractTree.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragments 8.2-8.5, 8.19-21
 | 
			
		||||
 *\
 | 
			
		||||
/*
 | 
			
		||||
 * an abstract base class providing some functionality of the tree interface.
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractTree<E> implements Tree<E> {
 | 
			
		||||
	public boolean isInternal(Position<E> p) {return numChildren(p)>0;}
 | 
			
		||||
	public boolean isExternal(Position<E> p){return numChildren(p)==0;}
 | 
			
		||||
	public boolean isRoot(Position<E> p){return p == root();}
 | 
			
		||||
	public boolean isEmpty(){return size()==0;}
 | 
			
		||||
 | 
			
		||||
	/**returns the number of levels sperating position p from the root.*/
 | 
			
		||||
	public int depth(Position<E> p){
 | 
			
		||||
		if (isRoot(p)){return 0;}
 | 
			
		||||
		else{return 1+depth(parent(p));}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**returns the hight of the tree.*/
 | 
			
		||||
	private int hightBad(){ //works, but quadratic worst case time.
 | 
			
		||||
		int h=0;
 | 
			
		||||
		for(Position<E> p : positions()){
 | 
			
		||||
			//only consider leaf positions.
 | 
			
		||||
			if(isExternal(p)){h=Math.max(h, depth(p));}
 | 
			
		||||
		}
 | 
			
		||||
		return h;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**returns the hight of the subtree rooted at position p.*/
 | 
			
		||||
	public int hight(Position<E> p){
 | 
			
		||||
		//base case if p is external
 | 
			
		||||
		int h=0;
 | 
			
		||||
		for (Position<E> c : children(p)){
 | 
			
		||||
			h=Math.max(h,1+hight(c));
 | 
			
		||||
		}
 | 
			
		||||
		return h;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	//iterators
 | 
			
		||||
	/**adds positions of the subtree rooted at position p to the given snapshot (for use in traversal)*/
 | 
			
		||||
	private void preorderSubtree(Position<E> p, List<Position<E>> snapshot){
 | 
			
		||||
		//for preorder, add position p before exploring subtrees.
 | 
			
		||||
		snapshot.add(p);
 | 
			
		||||
		for(Position<E> c:children(p)){
 | 
			
		||||
			preorderSubtree(c, snapshot);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**returns an iterable collection of positions in the tree, reported in preorder*/
 | 
			
		||||
	public Iterable<Position<E>> preorder(){
 | 
			
		||||
		List<Position<E>> snapshot=new ArrayList<>();
 | 
			
		||||
		//fill the snapshot recursively
 | 
			
		||||
		if(!isEmpty()){
 | 
			
		||||
			preorderSubtree(root(), snapshot);
 | 
			
		||||
		}
 | 
			
		||||
		return snapshot;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**adds positions of the subtree rooted at position p to the given snapshot (for use in traversal)*/
 | 
			
		||||
	private void postorderSubtree(Position<E> p, List<Position<E>> snapshot){
 | 
			
		||||
		//for postorder, add position p before exploring subtrees.
 | 
			
		||||
		for(Position<E> c:children(p)){
 | 
			
		||||
			postorderSubtree(c, snapshot);
 | 
			
		||||
		}
 | 
			
		||||
		snapshot.add(p);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**returns an iterable collection of positions in the tree, reported in postorder*/
 | 
			
		||||
	public Iterable<Position<E>> postorder(){
 | 
			
		||||
		List<Position<E>> snapshot=new ArrayList<>();
 | 
			
		||||
		//fill the snapshot recursively
 | 
			
		||||
		if(!isEmpty()){
 | 
			
		||||
			postorderSubtree(root(), snapshot);
 | 
			
		||||
		}
 | 
			
		||||
		return snapshot;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**returns an iterable collection of positions in the tree in breadth first traversal*/
 | 
			
		||||
	public Iterable<Position<E>> breadthFirst(){
 | 
			
		||||
		List<Position<E>> snapshot=new ArrayList<>();
 | 
			
		||||
		if(!isEmpty()){
 | 
			
		||||
			Queue<Position<E>> fringe=new LinkedQueue<>();
 | 
			
		||||
			fringe.enqueue(root());
 | 
			
		||||
			while(!fringe.isEmpty()){
 | 
			
		||||
				Position<E> p=fringe.dequeue();
 | 
			
		||||
				snapshot.add(p);
 | 
			
		||||
				for(Position<E> c:children(p)){
 | 
			
		||||
					fringe.enqueue(c);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return snapshot;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**default iterator*/
 | 
			
		||||
	public Iterable<Position<E>> positions(){return preorder();}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/ArrayQueue.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/ArrayQueue.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragment 6.10
 | 
			
		||||
 * 
 | 
			
		||||
 * An implementation of the ArrayQueue class
 | 
			
		||||
 * */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *implementation of the queue ADT using a fixed-length array.
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public class ArrayQueue<E> implements Queue<E>{
 | 
			
		||||
    //instance variables
 | 
			
		||||
    private E[] data;   //generic array used for storage
 | 
			
		||||
    private int f = 0;  //index of the front element
 | 
			
		||||
    private int sz = 0;   //current number of elements
 | 
			
		||||
    private static final int CAPACITY = 1000; //default capacity, book is missing this.
 | 
			
		||||
    
 | 
			
		||||
    //constructors
 | 
			
		||||
    /** constructs queue with default capacity*/
 | 
			
		||||
    public ArrayQueue(){this(CAPACITY);}
 | 
			
		||||
    /**constructs queue with given capacity*/
 | 
			
		||||
    public ArrayQueue(int capacity){
 | 
			
		||||
        data = (E[]) new Object[capacity];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    //methods
 | 
			
		||||
    /** returns the number of elements in the queue*/
 | 
			
		||||
    public int size(){return sz;}
 | 
			
		||||
    
 | 
			
		||||
    /** tests whether the queue is empty*/
 | 
			
		||||
    public boolean isEmpty(){return sz == 0;}
 | 
			
		||||
    
 | 
			
		||||
    /**inserts an element at the rear of the queue*/
 | 
			
		||||
    public void enqueue(E e) throws IllegalStateException{
 | 
			
		||||
        if(sz==data.length){throw new IllegalStateException("queue is full");}
 | 
			
		||||
        int avail = (f+sz)%data.length; //use modular arithmatic
 | 
			
		||||
        data[avail]=e;
 | 
			
		||||
        sz++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /** returns but does not remove the first element in the queue or null if emtpy*/
 | 
			
		||||
    public E first(){
 | 
			
		||||
        if(isEmpty()){return null;}
 | 
			
		||||
        return data[f];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /** removes and returns the first element of the queue or null if emtpy*/
 | 
			
		||||
    public E dequeue(){
 | 
			
		||||
        if(isEmpty()){return null;}
 | 
			
		||||
        E answer = data[f];
 | 
			
		||||
        data[f]=null; //dereference to help GC
 | 
			
		||||
        f=(f+1)%data.length;
 | 
			
		||||
        sz--;
 | 
			
		||||
        return answer;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/ArrayStack.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/ArrayStack.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragment 6.2
 | 
			
		||||
 * 
 | 
			
		||||
 * An implementation of an ArrayStack class
 | 
			
		||||
 * */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public class ArrayStack<E> implements Stack<E> {
 | 
			
		||||
    public static final int CAPACITY = 1000;//default capacity
 | 
			
		||||
    private E[] data;       //generic array used for storage.
 | 
			
		||||
    private int t=-1;       //index of the top element in the stack
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    //im swiching the authors comments to javadoc style, for ease of use.
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * constructs stack with default capacity
 | 
			
		||||
     */
 | 
			
		||||
    public ArrayStack(){this(CAPACITY);}
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * constructs stack with given capacity
 | 
			
		||||
     * @param capacity capacity to construct the stack with.
 | 
			
		||||
     */
 | 
			
		||||
    public ArrayStack(int capacity){
 | 
			
		||||
        data = (E[]) new Object[capacity];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public int size(){return (t+1);}
 | 
			
		||||
    
 | 
			
		||||
    public boolean isEmpty(){return(t==-1);}
 | 
			
		||||
    
 | 
			
		||||
    public void push(E e) throws IllegalStateException{
 | 
			
		||||
        if(size()==data.length){throw new IllegalStateException("Stack is full");}
 | 
			
		||||
        data[++t]=e; //increment t before storing a new item.
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public E top(){
 | 
			
		||||
        if(isEmpty()){return null;}
 | 
			
		||||
        return data[t];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public E pop(){
 | 
			
		||||
        if(isEmpty()){return null;}
 | 
			
		||||
        E answer = data[t];
 | 
			
		||||
        data[t] = null; //dereference to help with garbage collection.
 | 
			
		||||
        t--;
 | 
			
		||||
        return answer;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/BinaryTree.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/BinaryTree.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragments 8.6
 | 
			
		||||
 *\
 | 
			
		||||
 | 
			
		||||
\**
 | 
			
		||||
 *an interface for a binary tree, in which each node has at most two children.
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public interface BinaryTree<E> extends Tree<E> {
 | 
			
		||||
	/**returns the position of p's left child (or null if no child exists).*/
 | 
			
		||||
	Position<E> left(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
	/**returns the position of p's right child (or null if no child exists)*/
 | 
			
		||||
	Position<E> right(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
	/**returns the position of p's sibling (or null of no sibling exists).*/
 | 
			
		||||
	Position <E> sibling(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										189
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/LinkedBinaryTree.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/LinkedBinaryTree.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,189 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragments 8.9-11
 | 
			
		||||
 *\
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public class LinkedBinaryTree<E> extends AbstractBinaryTree<E> {
 | 
			
		||||
	
 | 
			
		||||
	//nested node class
 | 
			
		||||
	protected static class Node<E> implements Position<E>{
 | 
			
		||||
		//an element stored at this node
 | 
			
		||||
		private E element;
 | 
			
		||||
		//a reference the the parent node
 | 
			
		||||
		private Node<E> parent;
 | 
			
		||||
		//a refrence to the left node
 | 
			
		||||
		private Node<E> left;
 | 
			
		||||
		//a reference the right node
 | 
			
		||||
		private Node<E> right;
 | 
			
		||||
		
 | 
			
		||||
		/**constructs a done with the given element and neighbors*/
 | 
			
		||||
		public Node(E e, Node<E> above, Node<E> leftChild, Node<E> rightChild){
 | 
			
		||||
			element=e;
 | 
			
		||||
			parent=above;
 | 
			
		||||
			left=leftChild;
 | 
			
		||||
			right=rightChild;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		//why do we set the variables to private and make these methods for a protected class? doesnt that add uneeded overhead for no benifits of encapsulation?
 | 
			
		||||
		//acessor methods
 | 
			
		||||
		public E getElement(){return element;}
 | 
			
		||||
		public Node<E> getParent(){return parent;}
 | 
			
		||||
		public Node<E> getLeft(){return left;}
 | 
			
		||||
		public Node<E> getRight(){return right;}
 | 
			
		||||
		
 | 
			
		||||
		//update methods
 | 
			
		||||
		public void setElement(E e){element=e;}
 | 
			
		||||
		public void setParent(Node<E> parentNode){parent=parentNode;}
 | 
			
		||||
		public void setLeft(Node<E> leftChild){left=leftChild;}
 | 
			
		||||
		public void setRight(Node<E> rightChild){right=rightChild;}
 | 
			
		||||
	}//end of node class.
 | 
			
		||||
	
 | 
			
		||||
	//why create this class? its the exact same as just using the node constructor, even the same signature!
 | 
			
		||||
	/**factory function to create new node storing element e*/
 | 
			
		||||
	protected Node<E> createNode(E e, Node<E> parent, Node<E> left, Node<E> right){
 | 
			
		||||
		return new Node<E>(e, parent, left, right);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	//LinkedBinaryTree instance variables
 | 
			
		||||
	//root of the tree
 | 
			
		||||
	protected Node<E> root=null;
 | 
			
		||||
	//number of nodes in the tree
 | 
			
		||||
	private int size=0;
 | 
			
		||||
	
 | 
			
		||||
	//constructor
 | 
			
		||||
	//creats an empty binary tree
 | 
			
		||||
	public LinkedBinaryTree(){}
 | 
			
		||||
	
 | 
			
		||||
	//nonpublic utility
 | 
			
		||||
	/**validates the position and returns it as a node*/
 | 
			
		||||
	protected Node<E> validate(Position<E> p) throws IllegalArgumentException{
 | 
			
		||||
		if(!(p instanceof Node)){
 | 
			
		||||
			throw new IllegalArgumentException("not a valid position type");
 | 
			
		||||
		}
 | 
			
		||||
		//safe cast
 | 
			
		||||
		Node<E> node=(Node<E>)p;
 | 
			
		||||
		//our convention for a defunct node. Wont this make the GC not clean it up? why not just set the parent to null and let the GC clean it up?
 | 
			
		||||
		if(node.getParent()==node){
 | 
			
		||||
			throw new IllegalArgumentException("p is no longer in the tree");
 | 
			
		||||
		}
 | 
			
		||||
		return node;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	//acessor methods still left to implement
 | 
			
		||||
	/**returns the number of nodes in the tree*/
 | 
			
		||||
	public int size(){return size;}
 | 
			
		||||
	
 | 
			
		||||
	/**returns the root position of the tree (or null if tree is empty)*/
 | 
			
		||||
	public Position<E> root(){return root;}
 | 
			
		||||
	
 | 
			
		||||
	/**returns the position of p's parent or null if p is root*/
 | 
			
		||||
	public Position<E> parent(Position<E> p) throws IllegalArgumentException {
 | 
			
		||||
		Node<E> node=validate(p);
 | 
			
		||||
		return node.getParent();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**returns the position of p's left child (or null if no child exists)*/
 | 
			
		||||
	public Position<E> left(Position<E> p) throws IllegalArgumentException {
 | 
			
		||||
		Node<E> node = validate(p);
 | 
			
		||||
		return node.getLeft();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**returns the position of p's right child (or null if no child exists)*/
 | 
			
		||||
	public Position<E> right(Position<E> p) throws IllegalArgumentException {
 | 
			
		||||
		Node<E> node=validate(p);
 | 
			
		||||
		return node.getRight();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	//update methods supported
 | 
			
		||||
	/**places element e at the root of an empty tree and returns its new Position */
 | 
			
		||||
	public Position<E> addRoot(E e) throws IllegalStateException {
 | 
			
		||||
		if (!isEmpty()){throw new IllegalStateException("tree is not empty");}
 | 
			
		||||
		root=createNode(e, null, null, null);
 | 
			
		||||
		size=1;
 | 
			
		||||
		return root;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**creates a new left child of Position P storing element e, returns its position*/
 | 
			
		||||
	public Position<E> addLeft(Position<E> p, E e) throws IllegalArgumentException{
 | 
			
		||||
		Node<E> parent=validate(p);
 | 
			
		||||
		if(parent.getLeft()!=null){
 | 
			
		||||
			throw new IllegalArgumentException("p already has a left child");
 | 
			
		||||
		}
 | 
			
		||||
		Node<E> child=createNode(e, parent, null, null);
 | 
			
		||||
		parent.setLeft(child);
 | 
			
		||||
		size++;
 | 
			
		||||
		return child;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Position<E> addRight(Position<E> p, E e)throws IllegalArgumentException{
 | 
			
		||||
		Node<E> parent=validate(p);
 | 
			
		||||
		if(parent.getRight()!=null){
 | 
			
		||||
			throw new IllegalArgumentException("p already has a right child");
 | 
			
		||||
		}
 | 
			
		||||
		Node<E> child=createNode(e, parent, null, null);
 | 
			
		||||
		parent.setRight(child);
 | 
			
		||||
		size++;
 | 
			
		||||
		return child;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**replaces the element at position p with e and returns the replaced element*/
 | 
			
		||||
	public E set(Position<E> p, E e) throws IllegalArgumentException{
 | 
			
		||||
		Node<E> node=validate(p);
 | 
			
		||||
		E temp=node.getElement();
 | 
			
		||||
		node.setElement(e);
 | 
			
		||||
		return temp;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**attaches trees t1 and t2 as left and right subtrees of external p.*/
 | 
			
		||||
	public void attach(Position<E> p, LinkedBinaryTree<E> t1, LinkedBinaryTree<E> t2)throws IllegalArgumentException{
 | 
			
		||||
		Node<E> node=validate(p);
 | 
			
		||||
		if(isInternal(p)) throw new IllegalArgumentException("P must be a leaf");
 | 
			
		||||
		size+=t1.size()+t2.size();
 | 
			
		||||
		//set t1 as left node
 | 
			
		||||
		if(!t1.isEmpty()){
 | 
			
		||||
			t1.root.setParent(node);
 | 
			
		||||
			node.setLeft(t1.root);
 | 
			
		||||
			t1.root=null;
 | 
			
		||||
			t1.size=0;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		//set t2 as right node
 | 
			
		||||
		if(!t2.isEmpty()){
 | 
			
		||||
			t2.root.setParent(node);
 | 
			
		||||
			node.setRight(t2.root);
 | 
			
		||||
			t2.root=null;
 | 
			
		||||
			t2.size=0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
		/**removes the node at Position p and replaces it with its child. only works if p has 1 or 0 children*/
 | 
			
		||||
		public E remove(Position<E> p)throws IllegalArgumentException{
 | 
			
		||||
			Node<E> node=validate(p);
 | 
			
		||||
			if(numChildren(p)==2){throw new IllegalArgumentException("p has two children");}
 | 
			
		||||
			Node<E> child=(node.getLeft()!=null?node.getLeft():node.getRight());
 | 
			
		||||
			//childs grandparent becomes its parent
 | 
			
		||||
			if(child!=null){child.setParent(node.getParent());}
 | 
			
		||||
			
 | 
			
		||||
			//child becomes root;
 | 
			
		||||
			if(node==root){root=child;}
 | 
			
		||||
			//child is not root, set child as child of parent
 | 
			
		||||
			else{
 | 
			
		||||
				Node<E> parent = node.getParent();
 | 
			
		||||
				if(node==parent.getLeft()){parent.setLeft(child);}
 | 
			
		||||
				else{parent.setRight(child);}
 | 
			
		||||
			}
 | 
			
		||||
			size--;
 | 
			
		||||
			E temp=node.getElement();
 | 
			
		||||
			//help java GC. sometimes I think it would be easier to do manual GC than have to baby along an auto GC.
 | 
			
		||||
			node.setElement(null);
 | 
			
		||||
			node.setLeft(null);
 | 
			
		||||
			node.setRight(null);
 | 
			
		||||
			//for some reason we set this to parent itself, instead of setting to null and sending to GC.
 | 
			
		||||
			node.setParent(node);
 | 
			
		||||
			return temp;
 | 
			
		||||
		}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/LinkedQueue.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/LinkedQueue.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragment 6.11
 | 
			
		||||
 * 
 | 
			
		||||
 * An implementation of the LinkedQueue class
 | 
			
		||||
 * */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public class LinkedQueue<E> implements Queue<E>{
 | 
			
		||||
        private SinglyLinkedList<E> list = new SinglyLinkedList(); //an empty list
 | 
			
		||||
        public LinkedQueue(){} //new queue relies on initaly empty list
 | 
			
		||||
        public int size(){return list.size();}
 | 
			
		||||
        public boolean isEmpty(){return list.isEmpty();}
 | 
			
		||||
        public void enqueue(E element){list.addLast(element);}
 | 
			
		||||
        public E first(){return list.first();}
 | 
			
		||||
        public E dequeue(){return list.removeFirst();}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/Position.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/Position.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragment 7.7
 | 
			
		||||
 * 
 | 
			
		||||
 * An implementation of the position interface
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public interface Position<E> {
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the element stored at this position
 | 
			
		||||
     * 
 | 
			
		||||
     * @return the stored element
 | 
			
		||||
     * @throws IllegalStateException if position no longer valid.
 | 
			
		||||
     */
 | 
			
		||||
    E getElement() throws IllegalStateException;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragment 7.8
 | 
			
		||||
 * 
 | 
			
		||||
 * An implementation of the positionalList interface
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public interface PositionalList<E> {
 | 
			
		||||
    
 | 
			
		||||
    /** returns the number of elements in the list*/
 | 
			
		||||
    int size();
 | 
			
		||||
    
 | 
			
		||||
    /**tests whether the list is empty*/
 | 
			
		||||
    boolean isEmpty();
 | 
			
		||||
    
 | 
			
		||||
    /**returns the first position in the list (or null if empty)*/
 | 
			
		||||
    Position<E> first();
 | 
			
		||||
    
 | 
			
		||||
    /**returns the last position in the list (or null if empty)*/
 | 
			
		||||
    Position<E> last();
 | 
			
		||||
    
 | 
			
		||||
    /**returns the position immediately before position p (or null, if p is first)*/
 | 
			
		||||
    Position<E> before(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
    
 | 
			
		||||
    /**returns the position immediately after position p (or null, if p is last)*/
 | 
			
		||||
    Position<E> after(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
    
 | 
			
		||||
    /**inserts element e at the front of the list and returns its new position*/
 | 
			
		||||
    Position<E> addFirst(E e);
 | 
			
		||||
    
 | 
			
		||||
    /**inserts element e at the back of the list and returns its new position*/
 | 
			
		||||
    Position<E> addLast(E e);
 | 
			
		||||
    
 | 
			
		||||
    /**inserts element e immediately before position p and returns its new position*/
 | 
			
		||||
    Position<E> addBefore(Position<E> p, E e) throws IllegalArgumentException;
 | 
			
		||||
    
 | 
			
		||||
    /**inserts element e immediately after Position p and returns its new position*/
 | 
			
		||||
    Position<E> addAfter(Position<E> p, E e) throws IllegalArgumentException;
 | 
			
		||||
    
 | 
			
		||||
    /**replaces the element stored at position p and returns the replaced element*/
 | 
			
		||||
    E set(Position<E> p, E e) throws IllegalArgumentException;
 | 
			
		||||
    
 | 
			
		||||
    /**removes the element stored at position p and returns it (invalidating p)*/
 | 
			
		||||
    E remove(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/Queue.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/Queue.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragment 6.9
 | 
			
		||||
 * 
 | 
			
		||||
 * An implementation of the Queue interface
 | 
			
		||||
 * */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public interface Queue<E> {
 | 
			
		||||
    /** returns the number of elements in the queue*/
 | 
			
		||||
    int size();
 | 
			
		||||
    
 | 
			
		||||
    /** tests whether the queue is empty*/
 | 
			
		||||
    boolean isEmpty();
 | 
			
		||||
    
 | 
			
		||||
    /**inserts an element at the rear of the queue*/
 | 
			
		||||
    void enqueue(E e);
 | 
			
		||||
    
 | 
			
		||||
    /**returns, but does not remove, the first element of the queue (null if empty). */
 | 
			
		||||
    E first();
 | 
			
		||||
    
 | 
			
		||||
    /** removes and returns the first element of the queue (null if empty)*/
 | 
			
		||||
    E dequeue();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
/**
 | 
			
		||||
 *SinglyLinkedListClass
 | 
			
		||||
 * Code Fragments 3.14, 3.15
 | 
			
		||||
 * from
 | 
			
		||||
 * Data Structures & Algorithms, 6th edition
 | 
			
		||||
 * by Michael T. Goodrich, Roberto Tamassia & Michael H. Goldwasser
 | 
			
		||||
 * Wiley 2014
 | 
			
		||||
 * Transcribed by
 | 
			
		||||
 * @author Gabe Venberg
 | 
			
		||||
 */
 | 
			
		||||
public class SinglyLinkedList<E> {
 | 
			
		||||
    
 | 
			
		||||
    private static class Node<E> {
 | 
			
		||||
        private E element; //refrence to element stored at this node
 | 
			
		||||
        private Node<E> next; //refrence to subsequent node of list
 | 
			
		||||
        
 | 
			
		||||
        public Node(E e, Node<E> n){
 | 
			
		||||
            element = e;
 | 
			
		||||
            next = n;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public E getElement() {return element;}
 | 
			
		||||
        
 | 
			
		||||
        public Node<E> getNext() {return next;}
 | 
			
		||||
        
 | 
			
		||||
        public void setNext(Node<E> n) {next = n;}
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    //instance variables of SinglyLinkedList
 | 
			
		||||
    private Node<E> head = null;//head node of list
 | 
			
		||||
    private Node<E> tail = null;//last node of list
 | 
			
		||||
    private int size = 0;//number of nodes in list
 | 
			
		||||
    
 | 
			
		||||
    public SinglyLinkedList(){}//constructs an initaly empty list
 | 
			
		||||
    
 | 
			
		||||
    //access methods
 | 
			
		||||
    public int size() {return size;}
 | 
			
		||||
    
 | 
			
		||||
    public boolean isEmpty() {return size == 0;}
 | 
			
		||||
    
 | 
			
		||||
    public E first(){//returns but does not remove the first element
 | 
			
		||||
        if (size == 0) {return null;} //special case
 | 
			
		||||
        return head.getElement();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public E last(){//returns but does not remove last elemnt
 | 
			
		||||
        if (size ==0) {return null;}//special case
 | 
			
		||||
        return tail.getElement();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    //update methods
 | 
			
		||||
    public void addFirst(E e){//adds element e to the front of the list
 | 
			
		||||
        head = new Node<>(e, head);//create and link a new node
 | 
			
		||||
        if (size == 0) {tail = head;}//special case, head becomes tail also
 | 
			
		||||
        size++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public void addLast(E e){//adds element to end of list
 | 
			
		||||
        Node<E> newest = new Node<>(e, null);//create and link a new node
 | 
			
		||||
        if(size == 0){//special case, previously empty list
 | 
			
		||||
            head = newest;
 | 
			
		||||
        }
 | 
			
		||||
        else{
 | 
			
		||||
            tail.setNext(newest);//new node after existing tail
 | 
			
		||||
        }
 | 
			
		||||
        tail = newest;//new node becomes tail
 | 
			
		||||
        size++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public E removeFirst(){//removes and returns the first element
 | 
			
		||||
        if(size == 0){return null;}//nothing to remove
 | 
			
		||||
        E answer = head.getElement();
 | 
			
		||||
        head = head.getNext();//will become null if list had only one node.
 | 
			
		||||
        size--;
 | 
			
		||||
        if(size==0){tail = null;}// special case as list is now empty
 | 
			
		||||
        return answer;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/Stack.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/Stack.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragment 6.1
 | 
			
		||||
 * 
 | 
			
		||||
 * An implementation of the stack interface
 | 
			
		||||
 * */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A collection of objects that are inserted and removed according to a last-in
 | 
			
		||||
 * first-out principle. Although similar in purpose, this interface differs from
 | 
			
		||||
 * java.util.stack.
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public interface Stack<E> {
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * returns the number of elements in the stack
 | 
			
		||||
     * @return number of elements in the stack.
 | 
			
		||||
     */
 | 
			
		||||
    int size();
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * tests whether the stack is empty.
 | 
			
		||||
     * @return true if stack is empty, false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    boolean isEmpty();
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * inserts an element at the top of the stack.
 | 
			
		||||
     * @param e the element to be inserted.
 | 
			
		||||
     */
 | 
			
		||||
    void push(E e);
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * returns, but does not remove, the top element of the stack.
 | 
			
		||||
     * @return top element of the stack or null if empty.
 | 
			
		||||
     */
 | 
			
		||||
    E top();
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * removes and returns the top element from the stack.
 | 
			
		||||
     * @return element removed or null if empty.
 | 
			
		||||
     */
 | 
			
		||||
    E pop();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/Tree.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Lab108-VenbergGE/src/PrevAssignmentClasses/Tree.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Data Structures & Algorithms 6th Edition 
 | 
			
		||||
 * Goodrich, Tamassia, Goldwasser
 | 
			
		||||
 * Code Fragment 8.1
 | 
			
		||||
 * 
 | 
			
		||||
 * An implementation of the tree interface
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An interface for a tree where nodes can have an arbitrary number of children.
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
public interface Tree<E> extends Iterable<E>{
 | 
			
		||||
	Position <E> root();
 | 
			
		||||
	Position<E> parent(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
	Iterable<Position<E>> children(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
	int numChildren(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
	boolean isInternal(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
	boolean isExternal(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
	boolean isRoot(Position<E> p) throws IllegalArgumentException;
 | 
			
		||||
	int size();
 | 
			
		||||
	boolean isEmpty();
 | 
			
		||||
	Iterator<E> iterator();
 | 
			
		||||
	Iterable<Position<E>> positions();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										216
									
								
								Lab108-VenbergGE/src/ShuntingYard.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								Lab108-VenbergGE/src/ShuntingYard.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,216 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2021 Gabriel Venberg
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * a collection of static functions to parse expressions based on the shunting yard algorithm.
 | 
			
		||||
 * @author Gabriel Venberg
 | 
			
		||||
 */
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
public class ShuntingYard {
 | 
			
		||||
    /*
 | 
			
		||||
    change if-else-if to catch block in shunting yard
 | 
			
		||||
    keep things as strings for the whole process, assume if its not an operator or grouping symbol it must be a number (removes seperate validation logic)
 | 
			
		||||
    add order of operations logic, dont asusme it will be fully parenthisized
 | 
			
		||||
    validate parenthases using the shunting yard algo insead if seperate algo.
 | 
			
		||||
    */
 | 
			
		||||
//    /**
 | 
			
		||||
//     * returns a number based on the operator precedence.
 | 
			
		||||
//     * @param c string containing the operator.
 | 
			
		||||
//     * @return number representing the precedence of the operator.
 | 
			
		||||
//     */
 | 
			
		||||
//    private static int getPrecedence(String c){
 | 
			
		||||
//        
 | 
			
		||||
//    }
 | 
			
		||||
    /**
 | 
			
		||||
     * converts a space-delimited infix expression represented as a string to an arrayqueue postfix expression.
 | 
			
		||||
     * @param expression expression to be evaluated
 | 
			
		||||
     * @return  ArrayQueue of strings
 | 
			
		||||
     * @throws IllegalArgumentException 
 | 
			
		||||
     */
 | 
			
		||||
    public static ArrayQueue shuntingYard(String expression) throws IllegalArgumentException {
 | 
			
		||||
        ArrayQueue<String> output = new ArrayQueue<>();
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        ArrayStack<String> stack = new ArrayStack<>();
 | 
			
		||||
        
 | 
			
		||||
        //split into string array based on whitespace.
 | 
			
		||||
        String[] tokens = expression.split("\s");
 | 
			
		||||
        
 | 
			
		||||
        for(int i=0; i<tokens.length; i++){
 | 
			
		||||
            switch(tokens[i]){
 | 
			
		||||
                case "(":
 | 
			
		||||
                case "[":
 | 
			
		||||
                case "{":
 | 
			
		||||
                    stack.push(tokens[i]);
 | 
			
		||||
                    break;
 | 
			
		||||
                case ")":
 | 
			
		||||
                    //pop untill we find a maching bracket
 | 
			
		||||
                    while(!stack.top().equals("(")&&!stack.isEmpty()){
 | 
			
		||||
                        //if we encounter a different grouping symbol or run out of expression, then the grouping is wrong.
 | 
			
		||||
                        if(stack.top().equals("[")||stack.top().equals("{")||stack.isEmpty()){throw new IllegalArgumentException("invalid expression: mismached grouping");}
 | 
			
		||||
                        output.enqueue(stack.pop());
 | 
			
		||||
                    }
 | 
			
		||||
                    stack.pop();
 | 
			
		||||
                    break;
 | 
			
		||||
                case "]":
 | 
			
		||||
                    //pop untill we find a maching bracket
 | 
			
		||||
                    while(!stack.top().equals("[")&&!stack.isEmpty()){
 | 
			
		||||
                        //if we encounter a different grouping symbol or run out of expression, then the grouping is wrong.
 | 
			
		||||
                        if(stack.top().equals("{")||stack.top().equals("(")||stack.isEmpty()){throw new IllegalArgumentException("invalid expression: mismached grouping");}
 | 
			
		||||
                        output.enqueue(stack.pop());
 | 
			
		||||
                    }
 | 
			
		||||
                    stack.pop();
 | 
			
		||||
                    break;
 | 
			
		||||
                case "}":
 | 
			
		||||
                    //pop untill we find a maching bracket
 | 
			
		||||
                    while(!stack.top().equals("{")&&!stack.isEmpty()){
 | 
			
		||||
                        //if we encounter a different grouping symbol or run out of expression, then the grouping is wrong.
 | 
			
		||||
                        if(stack.top().equals("[")||stack.top().equals("(")||stack.isEmpty()){throw new IllegalArgumentException("invalid expression: mismached grouping");}
 | 
			
		||||
                        output.enqueue(stack.pop());
 | 
			
		||||
                    }
 | 
			
		||||
                    stack.pop();
 | 
			
		||||
                    break;
 | 
			
		||||
                case "+":
 | 
			
		||||
                case "-":
 | 
			
		||||
                    //while there is an operator with greater precedence
 | 
			
		||||
                    while(!stack.isEmpty()&&(stack.top().equals("*")||stack.top().equals("/"))){
 | 
			
		||||
                        output.enqueue(stack.pop());
 | 
			
		||||
                    }
 | 
			
		||||
                    stack.push(tokens[i]);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "*":
 | 
			
		||||
                case "/":
 | 
			
		||||
                    //there are no greater precedence operators
 | 
			
		||||
                    stack.push(tokens[i]);
 | 
			
		||||
                    break;
 | 
			
		||||
                //must be a number
 | 
			
		||||
                default:
 | 
			
		||||
                    output.enqueue(tokens[i]);
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        //empty the stack of leftovers.
 | 
			
		||||
        while(!stack.isEmpty()){
 | 
			
		||||
            output.enqueue(stack.pop());
 | 
			
		||||
        }
 | 
			
		||||
        return output;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * evaluates an array queue based postfix expression
 | 
			
		||||
     * @param inputExpression ArrayQueue of strings containing expression.
 | 
			
		||||
     * @return double containing the result of the expression.
 | 
			
		||||
     */
 | 
			
		||||
    public static double evalPostfix(ArrayQueue<String> inputExpression) throws IllegalArgumentException {
 | 
			
		||||
        //this took me a while to figure out. methods were consuming the queue...
 | 
			
		||||
        ArrayQueue<String> expression = new ArrayQueue();
 | 
			
		||||
        for(int i=0; i<inputExpression.size(); i++){
 | 
			
		||||
            expression.enqueue(inputExpression.first());
 | 
			
		||||
            inputExpression.enqueue(inputExpression.dequeue());
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        ArrayStack<Double> stack = new ArrayStack<>();
 | 
			
		||||
        while(!expression.isEmpty()){
 | 
			
		||||
            //compiler doesnt like declaring these inside switch statement.
 | 
			
		||||
            double right;
 | 
			
		||||
            double left;
 | 
			
		||||
            switch(expression.first()){
 | 
			
		||||
                case "-":
 | 
			
		||||
                    expression.dequeue();
 | 
			
		||||
                    right=stack.pop();
 | 
			
		||||
                    left=stack.pop();
 | 
			
		||||
                    stack.push(left-right);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "+":
 | 
			
		||||
                    expression.dequeue();
 | 
			
		||||
                    right=stack.pop();
 | 
			
		||||
                    left=stack.pop();
 | 
			
		||||
                    stack.push(left+right);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "*":
 | 
			
		||||
                    expression.dequeue();
 | 
			
		||||
                    right=stack.pop();
 | 
			
		||||
                    left=stack.pop();
 | 
			
		||||
                    stack.push(left*right);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "/":
 | 
			
		||||
                    expression.dequeue();
 | 
			
		||||
                    right=stack.pop();
 | 
			
		||||
                    left=stack.pop();
 | 
			
		||||
                    stack.push(left/right);
 | 
			
		||||
                    break;
 | 
			
		||||
                //must be number otherwise.
 | 
			
		||||
                default:
 | 
			
		||||
                    stack.push(Double.parseDouble(expression.dequeue()));
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        //at the end of this, there should be a single number.
 | 
			
		||||
        if(stack.size()!=1){
 | 
			
		||||
            String stackContents="";
 | 
			
		||||
            while(!stack.isEmpty()){
 | 
			
		||||
                stackContents=stackContents+stack.pop();
 | 
			
		||||
            }
 | 
			
		||||
            throw new IllegalArgumentException("stack does not have awnser! bug in evalPostFix! stack contains: "+stackContents);
 | 
			
		||||
        }
 | 
			
		||||
        return stack.pop();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * converts an arrayQueue infix expression to a linked binary tree output expression.
 | 
			
		||||
     * @param expression ArrayQueue containing expression. operators must be chars, numbers must be doubles.
 | 
			
		||||
     * @return linked binary tree representing the expression. operators are chars, numbers are doubles.
 | 
			
		||||
     */
 | 
			
		||||
    public static LinkedBinaryTree<String> convertToBinaryTree(ArrayQueue<String> inputExpression){
 | 
			
		||||
        //this took me a while to figure out. methods were consuming the queue...
 | 
			
		||||
        ArrayQueue<String> expression = new ArrayQueue<>();
 | 
			
		||||
        for(int i=0; i<inputExpression.size(); i++){
 | 
			
		||||
            expression.enqueue(inputExpression.first());
 | 
			
		||||
            inputExpression.enqueue(inputExpression.dequeue());
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        ArrayStack<LinkedBinaryTree<String>> stack = new ArrayStack<>();
 | 
			
		||||
        while(!expression.isEmpty()){
 | 
			
		||||
            //check if operator
 | 
			
		||||
            switch(expression.first()){
 | 
			
		||||
                case "+":
 | 
			
		||||
                case "-":
 | 
			
		||||
                case "*":
 | 
			
		||||
                case "/":
 | 
			
		||||
                    LinkedBinaryTree<String> newOperatorTree=new LinkedBinaryTree<>();
 | 
			
		||||
                    newOperatorTree.addRoot(expression.dequeue());
 | 
			
		||||
                    //need temp variables, as attach want new left child as first argument, but top of stack is new right child here.
 | 
			
		||||
                    LinkedBinaryTree newRight=stack.pop();
 | 
			
		||||
                    LinkedBinaryTree newLeft=stack.pop();
 | 
			
		||||
                    newOperatorTree.attach(newOperatorTree.root(), newLeft, newRight);
 | 
			
		||||
                    stack.push(newOperatorTree);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                //must be number
 | 
			
		||||
                default:
 | 
			
		||||
                    LinkedBinaryTree<String> newNumberTree=new LinkedBinaryTree<>();
 | 
			
		||||
                    newNumberTree.addRoot(expression.dequeue());
 | 
			
		||||
                    stack.push(newNumberTree);
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        //after the loop, should be the completed tree as only value on stack.
 | 
			
		||||
        return stack.pop();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
		Reference in a new issue