The goal of this assignment is to practice using Vectors and linked lists.
As usual, make a new directory for this project and cd into it.
A stack is a container for data (a data structure) characterized by the ability to add elements and then retrieve them in the opposite order from which they were added. For a real-world analogy, think of a PEZ dispenser. Suppose you added to an empty dispenser a red piece, a green piece, and a blue piece, one at a time and in that order. You would not then be able to get at the red piece directly. Instead, if you opened the head, you could retrieve the blue piece, and then the green and red, in that order. The order in which you remove the pieces is the reverse of the order in which you added them. This is called last-in/first-out (LIFO) order.
More formally, a stack is a data structure that has the following operations:
(Sometimes pop's responsibilities are divided among two operations: top, which returns the top element but does not remove it, and pop, which removes the top element but does not return it. For our purposes, we'll assume a single pop operation that does both.)
Consider this illustration of executing a push and two pops on a stack of characters that already has three elements in it:
Note that a set of operations essentially defines an interface. There is more than one way to implement a stack, as we will see in this assignment.
Note also that the way you interact with a stack is fundamentally different from how you interact with an array (although we can use an array to implement a stack). In an array, you can read from or write to any position at any time (this is called random access). In a stack, you can interact only with the end of the stack, regardless of what position the end is.
Copy the following files from the class directory:
> cp /homeemp/tvandrun/pub/241/Stack.java . > cp /homeemp/tvandrun/pub/241/StackDriver.java . > cp /homeemp/tvandrun/pub/241/ArrayStack.java . > cp /homeemp/tvandrun/pub/241/VectorStack.java . > cp /homeemp/tvandrun/pub/241/ListStack.java . > cp /homeemp/tvandrun/pub/241/ListNode.java .
Stack.java
contains an interface for stack-like classes.
StackDriver.java
contains a driver to test various
implementations of Stack.java
.
It uses the stacks for a classic stack application: reversing
strings.
Familiarize yourself with these.
Note that StackDriver.java
chops strings up into
one-character-long String
s rather than
char
s.
This will make using a Vector
to implement
a stack easier.
ArrayStack.java
defines a class that implements
a stack using an array.
It is already finished for you.
Your first task is to inspect this code carefully and understand how it works.
Note that the instance variable top
always points to the
next available slot.
Note also that position 0 is always the bottom of the stack,
and the stack grows "up" (more like a stack of books on a table
which gets higher the more books you put on it than
like a PEZ dispenser that grows "down" as the string compresses).
Finish the file VectorStack.java
so that it
defines a class that works just
like ArrayStack
, but uses a Vector
in place of an array.
Un-comment the relevant lines in the driver to test your class.
Since Vector
s can grow to be arbitrarily large,
isFull()
should always return false---the
stack will never be full.
A simple way of doing this is to follow the ArrayStack
class to a T (except for isFull()
), just "translating"
the array subscripting and such to use the Vector
methods
instead.
After all, a Vector
is basically an expandable array.
However, there's a more sophisticated way to do this that makes better
use of the powerful methods the Vector
class has.
For example, you could do without a top
instance variable.
There is a summary of some Vector
methods on pages
616-619 in our textbook, but more can be found at
the
Vector
webpage in the Java API.
Finally, implement a stack using a linked list in
ListStack.java
, and uncomment the relevant
lines in the driver to test it.
As with the Vector
version, the stack should never
be full.
Use the ListNode
class provided.
You may modify it if you wish, but you will not need to.
Hint: Make the head of the list be the top element
of the stack; that is the only instance variable you will need.
Once you see the intuition there, the methods are very simple, most
being a single line long.
Also, I cannot see why you would ever need to use the setter methods
in ListNode
.
Create the script file as before (cat--only files you've written or changed, rm, compile, and run)
> a2ps -P sp (the name of the script file)
(This will print "two up", meaning two pages shown next to each other
on one pice of paper. If you use a2ps
on a Java file, it
will format it nicely like in the handouts I've given in class.
The command lpr
works similarly except it does no formatting
and doesn't print two up by default.)
Then turn in the hard copy by 5:00, Mon, Apr 25.