/* * a stack implemented using a linked list * @author Biagioni, Edoardo * @assignment lecture 7 * @date February 4, 2008 */ import java.util.EmptyStackException; public class LinkedStack<E> implements StackInterface<E> { // the stack is stored in linked nodes /** * A node in a singly-linked list * @author Edo Biagioni * @lecture ICS 211 Jan 27 or later * @date January 26, 2010 * @bugs private class: include this code within a larger class */ private static class LinkedNode<T> { private T item; private LinkedNode<T> next; /** * constructor to build a node with no successor * @param the value to be stored by this node */ private LinkedNode(T value) { item = value; next = null; } /** * constructor to build a node with a specified (perhaps null) successor * @param the value to be stored by this node * @param the next field for this node */ private LinkedNode(T value, LinkedNode<T> reference) { item = value; next = reference; } } protected LinkedNode<E> top; /* no-arguments default constructor creates an empty stack */ public LinkedStack() { top = null; // empty stack } /* @return whether the stack is empty */ public boolean empty() { return (top == null); } /* @param value to push onto the stack */ public void push(E value) { top = new LinkedNode<E>(value, top); } /* @return the top value on the stack */ public E pop() throws EmptyStackException { if (empty()) { throw new EmptyStackException(); } E result = top.item; top = top.next; return result; } /* @return the top value on the stack */ public E peek() throws EmptyStackException { if (empty()) { throw new EmptyStackException(); } return top.item; } /* convert the stack to a printable string * @return a string representing the stack */ public String toString() { if (empty()) { return "Empty Stack"; } else { return recursiveToString(top); } } /* recursive method to print a non-empty stack * @param the starting index in the array * @return a string representing the stack */ private String recursiveToString(LinkedNode<E> startNode) { if (startNode == null) { return ""; } String separator = ""; if (startNode != top) { // add :: after each item (but not at start) separator = " :: "; } return separator + startNode.item + recursiveToString(startNode.next); } // simple test public static void main(String[] args) { StackInterface<String> s = new ArrayStack<String>(); System.out.println("before pushing anything, " + s); s.push("hello"); s.push("world"); System.out.println("after pushing hello and world, " + s); System.out.println("pop returns " + s.pop()); System.out.println("after popping, " + s); StackInterface<Integer> si = new ArrayStack<Integer>(); // push 100 values for (int i = 0; i < 100; i++) { si.push(i); } // now pop them and make sure the same values are returned // in LIFO order for (int i = 99; i >= 0; i--) { Integer returned = si.pop(); if (! returned.equals(i)) { System.out.println("error: pop returns " + returned + ", expected " + i); } } s.push("a"); s.push("beautiful"); s.push("day"); System.out.println("after pushing 'a beautiful day', " + s); System.out.println("pop returns " + s.pop()); System.out.println("pop returns " + s.pop()); System.out.println("pop returns " + s.pop()); System.out.println("pop returns " + s.pop()); System.out.println("after popping, " + s); /* expected output: * before pushing anything, Empty Stack * after pushing hello and world, hello :: world * pop returns world * after popping, hello * after pushing 'a beautiful day', hello :: a :: beautiful :: day * pop returns day * pop returns beautiful * pop returns a * pop returns hello * after popping, Empty Stack */ } }