| 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.
The main goal of this lab is to gain facility with two common methods of implementing the data organization type called stacks.
Create a stack package within Eclipse for use throughout this lab.
The reading describes a stack as an object that can store data and that has the following operations:
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;
}
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.
Complete the implementation of a stack of strings by implementing the these the constructor and all additional stack operations.
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.
Add the following methodsto the code:
public int size ( )
(returns the number of items currently on the stack)
public void print ( )
(prints all of the current elements on the stack)
public E get_nth (int nth)
(returns the item at the nth position from the top of the
stack)
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;
}
/* a stack constructor */ public boolean isEmpty (stringStack stack) public boolean isFull (stringStack stack) E pop ( ) E push (E item) E top ( )
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.
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.
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.