Assignment 12: Vectors and linked lists

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.

1. Introduction

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.

2. Implementing a stack with an array.

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 Strings rather than chars. 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).

3. Implementing a stack with a Vector

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 Vectors 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.

4. Implementing a stack using a linked list

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.

5. Turn in

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.


Thomas VanDrunen
Last modified: Thu Apr 7 13:31:34 CDT 2005