Please send questions to
st10@humboldt.edu .
//---------------------------------------------------------------------
// File: stack.template
// Name: Sharon M. Tuttle
// last modified: 4-01-05
//
// Template class name: stack
//
// Purpose: a collection of items such that entries can be
// Inserted and removed at only one end (called the top)
//
// Implementation notes:
// * uses a linked list of elements of the node template class
// * if there is insufficient dynamic memory, then the
// following methods throw bad_alloc: push
//---------------------------------------------------------------------
#include <cassert> // provides assert
//
// note: because this is a template class, it is included
// in the header file (at the bottom), and not compiled
// separately. Thus, the header file is not included here!
//
#include "node.h"
using namespace std;
/*****************************************************/
/* CONSTRUCTORS and DESTRUCTOR */
/*****************************************************/
// constructor
//
// postcondition: creates an empty stack instance
//
template <typename Item>
stack<Item>::stack()
{
top = NULL;
used = 0;
}
// copy constructor
//
// adapted from list_copy, Savitch and Main
//
template <typename Item>
stack<Item>::stack(const stack<Item>& source)
{
node<Item> *source_curr, *new_curr;
// start copy out as empty, but with the same value of used
// as the source being copied
top = NULL;
used = source.used;
// handle the case of the empty stack
if (source.top == NULL)
{
return; // source is empty, so this copy is, too
}
// if source is NOT empty, make a copy of it
// cause new copy to now have source top's data;
top = new node<Item>(source.top->get_data());
// start a pointer walking through the new copy
// starting from its top
new_curr = top;
// is there another in the source left to be copied?
source_curr = source.top->get_next();
// while there is another node in the source left
// to be copied...
while (source_curr != NULL)
{
// add a new node to the new copy with the data in
// that node;
new_curr->set_next(new node<Item>(source_curr->get_data()));
// move the new copy's pointer to the new node
new_curr = new_curr->get_next();
// is there another in the source left to be copied?
source_curr = source_curr->get_next();
}
}
// destructor
//
template <typename Item>
stack<Item>::~stack()
{
node<Item> *curr_ptr, *node_to_delete;
curr_ptr = top;
// need to deallocate EACH node in the stack
while (curr_ptr != NULL)
{
node_to_delete = curr_ptr;
curr_ptr = curr_ptr->get_next();
delete node_to_delete;
}
// playing it safe...
top = NULL;
used = 0;
}
/*************************************************************/
/* ACCESSORS and other constant member functions (observers) */
/*************************************************************/
// is_empty
//
// postcondition: returns true if stack is empty, and
// returns false otherwise
//
template <typename Item>
bool stack<Item>::is_empty( ) const
{
return (used == 0);
}
// get_top
//
// precondition: is_empty() == false
//
// postcondition: returns the value of the top item of the
// stack, BUT the stack is unchanged.
//
template <typename Item>
Item stack<Item>::get_top( ) const
{
assert(is_empty() == false);
return(top->get_data());
}
/*****************************************************/
/* MODIFIERS and other modifying member functions */
/*****************************************************/
// push
//
// postcondition: a new copy of entry has been pushed
// onto the (top of the) stack
//
template <typename Item>
void stack<Item>::push(const Item& entry)
{
node<Item> *temp;
temp = new node<Item>(entry);
// new top element's next field needs to point to
// "old" top element
temp->set_next(top);
// now, top can safely be made to point to new top
// element
top = temp;
used++;
}
// pop
//
// precondition: is_empty() == false
//
// postcondition: the top item of the stack has been
// removed, and a reference to it is returned
//
template <typename Item>
Item stack<Item>::pop( )
{
value_type popped_item;
node<Item>* temp;
assert(is_empty() == false);
used--;
// remember: if we reach here, we KNOW that stack is
// not empty
popped_item = top->get_data();
// keep track of item to be removed
temp = top;
// now it should be safe to make top point to the
// new top element
top = top->get_next();
// free the space for this popped node from the heap,
// so it be be re-allocated for other uses
delete temp;
return popped_item;
}