Stack
API
public interface Stack<Item> extends Iterable<Item>
{
public void push(Item item);
public Item pop();
public boolean isEmpty();
public int size();
}
Implementation
Fixed size array
/*************************************************************************
* Compilation: javac FixedCapacityStack.java
* Execution: java FixedCapacityStack
*
* Generic stack implementation with a fixed-size array.
*
* % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java FixedCapacityStack 5 < tobe.txt
* to be not that or be
*
* Remark: bare-bones implementation. Does not do repeated
* doubling or null out empty array entries to avoid loitering.
*
*************************************************************************/
import java.util.Iterator;
public class FixedCapacityStack<Item> implements Iterable<Item> {
private Item[] a;
private int N;
public FixedCapacityStack(int capacity) {
a = (Item[]) new Object[capacity];
}
public boolean isEmpty() { return (N == 0); }
public void push(Item item) { a[N++] = item; }
public Item pop() { return a[--N]; }
public Iterator<Item> iterator() { return new ReverseArrayIterator(); }
public class ReverseArrayIterator implements Iterator<Item> {
private int i = N-1;
public boolean hasNext() { return i >= 0; }
public Item next() { return a[i--]; }
public void remove() { throw new UnsupportedOperationException(); }
}
public static void main(String[] args) {
int max = Integer.parseInt(args[0]);
FixedCapacityStack<String> stack = new FixedCapacityStack<String>(max);
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) stack.push(item);
else if (stack.isEmpty()) StdOut.println("BAD INPUT");
else StdOut.print(stack.pop() + " ");
}
StdOut.println();
StdOut.print("Left on stack: ");
for (String s : stack) {
StdOut.print(s + " ");
}
StdOut.println();
}
}
Resizing array
/*************************************************************************
* Compilation: javac ResizingArrayStack.java
* Execution: java ResizingArrayStack < input.txt
* Data files: http://algs4.cs.princeton.edu/13stacks/tobe.txt
*
* Stack implementation with a resizing array.
*
* % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java ResizingArrayStack < tobe.txt
* to be not that or be (2 left on stack)
*
*************************************************************************/
import java.util.Iterator;
import java.util.NoSuchElementException;
public class ResizingArrayStack<Item> implements Iterable<Item> {
private Item[] a;
private int N;
public ResizingArrayStack() {
a = (Item[]) new Object[2];
}
public boolean isEmpty() { return N == 0; }
public int size() { return N; }
private void resize(int capacity) {
assert capacity >= N;
Item[] temp = (Item[]) new Object[capacity];
for (int i = 0; i < N; i++) {
temp[i] = a[i];
}
a = temp;
}
public void push(Item item) {
if (N == a.length) resize(2*a.length);
a[N++] = item;
}
public Item pop() {
if (isEmpty()) throw new NoSuchElementException("Stack underflow");
Item item = a[N-1];
a[N-1] = null;
N--;
if (N > 0 && N == a.length/4) resize(a.length/2);
return item;
}
public Iterator<Item> iterator() { return new ReverseArrayIterator(); }
private class ReverseArrayIterator implements Iterator<Item> {
private int i;
public ReverseArrayIterator() {
i = N;
}
public boolean hasNext() {
return i > 0;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
return a[--i];
}
}
/***********************************************************************
* Test routine.
**********************************************************************/
public static void main(String[] args) {
ResizingArrayStack<String> s = new ResizingArrayStack<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) s.push(item);
else if (!s.isEmpty()) StdOut.print(s.pop() + " ");
}
StdOut.println("(" + s.size() + " left on stack)");
}
}
linked list
/*************************************************************************
* Compilation: javac Stack.java
* Execution: java Stack < input.txt
*
* A generic stack, implemented using a linked list. Each stack
* element is of type Item.
*
* % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java Stack < tobe.txt
* to be not that or be (2 left on stack)
*
*************************************************************************/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>Stack</tt> class represents a last-in-first-out (LIFO) stack of generic items.
* It supports the usual <em>push</em> and <em>pop</em> operations, along with methods
* for peeking at the top item, testing if the stack is empty, and iterating through
* the items in LIFO order.
* <p>
* All stack operations except iteration are constant time.
* <p>
* For additional documentation, see <a href="/algs4/13stacks">Section 1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
*/
public class Stack<Item> implements Iterable<Item> {
private int N;
private Node first;
private class Node {
private Item item;
private Node next;
}
/**
* Create an empty stack.
*/
public Stack() {
first = null;
N = 0;
assert check();
}
/**
* Is the stack empty?
*/
public boolean isEmpty() {
return first == null;
}
/**
* Return the number of items in the stack.
*/
public int size() {
return N;
}
/**
* Add the item to the stack.
*/
public void push(Item item) {
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
N++;
assert check();
}
/**
* Delete and return the item most recently added to the stack.
* @throws java.util.NoSuchElementException if stack is empty.
*/
public Item pop() {
if (isEmpty()) throw new NoSuchElementException("Stack underflow");
Item item = first.item;
first = first.next;
N--;
assert check();
return item;
}
/**
* Return the item most recently added to the stack.
* @throws java.util.NoSuchElementException if stack is empty.
*/
public Item peek() {
if (isEmpty()) throw new NoSuchElementException("Stack underflow");
return first.item;
}
/**
* Return string representation.
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
private boolean check() {
if (N == 0) {
if (first != null) return false;
}
else if (N == 1) {
if (first == null) return false;
if (first.next != null) return false;
}
else {
if (first.next == null) return false;
}
int numberOfNodes = 0;
for (Node x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N) return false;
return true;
}
/**
* Return an iterator to the stack that iterates through the items in LIFO order.
*/
public Iterator<Item> iterator() { return new ListIterator(); }
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* A test client.
*/
public static void main(String[] args) {
Stack<String> s = new Stack<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) s.push(item);
else if (!s.isEmpty()) StdOut.print(s.pop() + " ");
}
StdOut.println("(" + s.size() + " left on stack)");
}
}