CS 261 University of Puget Sound Spring, 2020
 
Computer Science II
Abstract Data Types and their Implementations, Some Basic Algorithms,
Object-oriented Problem Solving, and Efficiency
 

Warning: This course is under development. Although the basic structure of this course is largely established, nothing on this Web site should be considered official or even possibly correct.
DO NOT MAKE PLANS BASED ON THE CONTENTS OF THIS SITE UNTIL JANUARY, 2020.

Laboratory Exercise on Stacks

Goals

The main goal of this lab is to gain facility with two common methods of implementing the data organization type called stacks.

Work Started in Class

Create a stack package within Eclipse for use throughout this lab.


Part A: Stacks with Arrays

The reading describes a stack as an object that can store data and that has the following operations:

A Potential Stack Interface in Java

As suggested in the reading on the stack abstract data type, the followng interface might be used for a generic stack with items of type E.

  /* a constructor for an empty stack
   */

  /* return whether the stack is empty
     pre:  stack is an initialized stack
     post: returns true if stack is empty;
           false otherwise
   */
  public boolean isEmpty ()

  /* return whether the stack is full
     pre:  stack is an initialized stack
     post: returns true if an additional item
              can be added to the stack;
           false otherwise
   */
  public boolean isFull ()

  /* insert given item onto top of the stack
     pre:  the specified stack is initialized
     returns:  null if stack is full
               otherwise, reference to item added
   */
  public E push (E item) 

  /* removes top item from stack referenced by parameter
     pre:  the specified stack is initialized
     returns:  null if stack is empty
               otherwise, reference to the item removed
   */
  E pop ()

  /* returns a pointer to top item on the stack
     pre:  the specified stack is initialized
     returns:  null if stack is empty
               otherwise, reference to the item returned
   */
  E top ()

For this section of the lab, we will focus on arrays of items of type E, and this leads to the following declarations for stacks of fruits, vegetables, and pastries:

   public class Stack <E> {

     protected int topPosition;
     protected E [] stackData;

With this framework, the isFull and push operations might be defined as follows:

  public boolean isFull ( ) {
  /* determine if an item can be added to the stack */
  return (this.topPosition == (MaxStack-1));
  }
   int push (E item) {
  /* return null if stack full */
  if (isFull ( )) {
     return null;
  }
   /* add item to stack */
  this.topPosition ++;
  this.stackArray[this.topPosition] = item;
  }

Interpreting topPosition

Within a stack, the topPosition field typically represents the location in the stackArray containing the most recent item pushed onto the stack. This is the index of the stackArray that contains the item accessed by the top function and the item returned by the pop function.

With this interpretation, suppose exactly one item has been pushed onto the stack. Then the item would be stored in stackArray[0], and the topPosition field should contain the index 0. Similarly, if the number of items in the stack were MaxStack, then they would be stored in stackArray[0], ..., stackArray[MaxStack-1], and topPosition field should contain the index MaxStack-1.

Following this interpretation, what value is appropriate for the topPosition field, if the stack is empty? Since the value should be 0 when the stack contains one item, and since the value is incremented by 1 for each push operation, the appropriate value for the the topPosition field for an empty stack should be -1. With this initialization, the first push would increment the topPosition field to 0, and that is the position where the new item would be referenced.

Similarly, if the topPosition field contained the value MaxStack-1, then all locations in the stackArray would contain items, and the stack would be full.


  1. Complete the implementation of a stack of strings by implementing the these the constructor and all additional stack operations.

  2. After writing functions, it is important to test your code to ensure that it works as you expected and accounts for unusual cases. Declare and initialize three stacks within your main program for fruit, vegetables, and pastry. Test your code by executing the following instructions:

    • Push "apple" and "orange" onto the fruit stack.

    • Push "doughnut" onto the pastry stack.

    • Check if the three stacks are empty.

    • Push "corn", "beans", "squash", and "broccoli" onto the vegetable stack.

    • Print the top of each stack.

    • Pop one item off the pastry stack and print it.

    • Print the top of each stack.

      Hint: the pastry stack is empty. Be careful!

    • Pop three items off the vegetable stack and print.

    • Pop three items off the fruit stack and print.

      Hint: how many items are on the fruit stack initially?

    • Push "cake" onto the pastry stack.

    • Check if any of the three stacks is empty.


Homework

    Add the following methodsto the code:


Part B: Stacks with Linked Lists

The reading regarding the linked list implementation of stacks discusses the stack functions in the context of linked lists. Nodes for this list might utilize this class definition:

  public class StackNode {
     E data;
     StackNode next;
  }
  /* getters and/or setters follow */

With this defintion of a node, a stack class might begin with the following:

   public class StackAsList {
      StackNode firstNode;
      
      /* constructor */
      public StackAsList ( ) {
         firstNode = null;
      }

Reminder: Common Function Prototypes for Stacks

  /* a stack constructor */
  public boolean isEmpty (stringStack stack)
  public boolean isFull (stringStack stack)      
  E pop ( ) 
  E push (E item) 
  E top ( )

  1. Copy the stack class you wrote for the earlier section on stacks with arrays to yield a new class StackAsList. Then modify it, so that the stacks are implemented by linked lists. In this, you will need to change the bodies of the methods.

  2. For testing, you likely can use the same code as before, creating three new stack objects (for fruits, vegetables, and pastries). Since the method interfaces are the same, you should not have to change any of the code used for testing, and the output of this new program should be identical in all respects to the output of the program from the previous section.

  3. As with the previous lab on stacks with arrays, expand the code for the stack ADT implementation to include these functions:

    • a size function which will return the number of items currently on the stack,

    • a print function which will print all of the current elements on the stack, and

    • an nth function which takes one parameter (an index) and returns the item at that position from the top in the current stack.



created 16 August 2011 by April O'Neill
Several exercises borrowed from/inspired by Henry Walker's spring 2010 CS161 labs on stacks
revised 16 August 2011 by April O'Neill
revised 5 December 2011 by Erik Opavsky
revised 7 December 2011 by Henry M. Walker
revised 26 April 2013 by Henry M. Walker
reformatted 3 February 2014 by Henry M. Walker
readings added 19 September 2014 by Henry M. Walker
Empty, Full renamed 20 April 2015 by Henry Walker
Revised to updated format 14 April 2016 by Henry Walker updated for Java 1 February 2020 by Henry Walker
Valid HTML 4.01! Valid CSS!