Please send questions to
st10@humboldt.edu .
/************************************************************/
/* ADAPTED FROM: */
/* http://www.cs.colorado.edu/~main/chapter4/node1.cxx */
/* */
/* Main and Savitch, "Data Structures and Other Objects */
/* using C++", 2nd edition, Addison-Wesley, Ch.5 */
/************************************************************/
//---------------------------------------------------------------------
// File: node.template
// Name: Michael Main, Walter Savitch
// (adapted by Sharon M. Tuttle)
// last modified: 4-20-05 - now includes linked-list "toolkit" functions
//
// Template class name: node
//
// Purpose: serves as the unit from which a singly-linked list
// can be built.
//
// DYNAMIC MEMORY USAGE by the node class:
// If there is insufficient dynamic memory, then the
// following throw bad_alloc:
// the constructors
//
// NOTE:
// Some of the methods have return value that is
// a pointer to a node. Each of these comes in TWO
// versions: a non-const version (where the return value is
// node*) and a const version (where the return value is
// const node*).
//---------------------------------------------------------------------
#include <cassert>
#include "node.h"
using namespace std;
/*****************************************************/
/* CONSTRUCTORS and DESTRUCTOR */
/*****************************************************/
// postcondition: creates a node with data_field obtained from
// the default constructor of the value_type, and
// next_field set to NULL.
//
// NOTE: In the ANSI/ISO standard, this default-constructor
// notation is also allowed for the built-in types,
// providing a default value of zero.
//
template <typename Item>
node<Item>::node( )
{
data_field = value_type();
next_field = NULL;
}
// postcondition: creates a node with data_field set to
// init_data, and next_field set to NULL.
//
template <typename Item>
node<Item>::node(const value_type& init_data)
{
data_field = init_data;
next_field = NULL;
}
// postcondition: create a node with data_field obtained from
// the default constructor of the value_type, and
// next_field set to init_next.
//
template <typename Item>
node<Item>::node(node<Item>* init_next)
{
data_field = value_type();
next_field = init_next;
}
// postcondition: create a node with data_field set to
// init_data, and next_field set to init_next.
//
template <typename Item>
node<Item>::node(const value_type& init_data, node<Item>* init_next)
{
data_field = init_data;
next_field = init_next;
}
/*************************************************************/
/* ACCESSORS and other constant member functions (observers) */
/*************************************************************/
// get_data
//
// postcondition: returns the data from this node
//
template <typename Item>
typename node<Item>::value_type node<Item>::get_data( ) const
{
return data_field;
}
// get_next
//
// postcondition: returns the next pointer from this node.
// (See note above --- need both a const and non-const
// version of this, because it returns a pointer.
// See also pp. 219-221 of Savitch and Main, 3rd edition.)
//
template <typename Item>
const node<Item>* node<Item>::get_next( ) const
{
return next_field;
}
template <typename Item>
node<Item>* node<Item>::get_next( )
{
return next_field;
}
/*****************************************************/
/* MODIFIERS and other modifying member functions */
/*****************************************************/
// set_data
//
// postcondition: the node now contains the specified
// new_data.
//
template <typename Item>
void node<Item>::set_data(const value_type& new_data)
{
data_field = new_data;
}
// set_next
//
// postcondition: the node now contains the specified
// new_next pointer.
//
template <typename Item>
void node<Item>::set_next(node<Item>* new_next)
{
next_field = new_next;
}
/*****************************************************/
/* LINKED LIST "TOOLKIT" FUNCTIONS */
/* */
/* functions to manipulate a linked list */
/*****************************************************/
// list_clear
//
// precondition: head_ptr is the head pointer of a linked list.
// postconditions: All nodes of the list have been returned
// to the heap, and the head_ptr is now NULL.
// (thus, the need for head_ptr to be passed BY REFERENCE...)
//
template <typename Item>
void list_clear(node<Item>*& head_ptr)
{
while (head_ptr != NULL)
{
list_head_remove(head_ptr);
}
}
// list_copy
//
// precondition: source_ptr is the head pointer of a linked list.
// postconditions: head_ptr and tail_ptr are the head and tail
// pointers for a new list that contains the same items as the
// list pointed to by source_ptr. The original list is unaltered.
//
template <typename Item>
void list_copy
(const node<Item>* source_ptr, node<Item>*& head_ptr, node<Item>*& tail_ptr)
{
head_ptr = NULL;
tail_ptr = NULL;
// Handle the case of the empty list
if (source_ptr == NULL)
{
return;
}
// Make the head node for the newly created list, and put data
// in it
list_head_insert(head_ptr, source_ptr->get_data( ));
tail_ptr = head_ptr;
// Copy rest of the nodes one at a time, adding at the tail of
// new list
source_ptr = source_ptr->get_next( );
while (source_ptr != NULL)
{
list_insert(tail_ptr, source_ptr->get_data( ));
tail_ptr = tail_ptr->get_next( );
source_ptr = source_ptr->get_next( );
}
}
// list_head_insert
//
// precondition: head_ptr is the head pointer of a linked list.
// postconditions: A new node containing the given entry has been
// added at the head of the linked list; head_ptr now points to
// the head of the new, longer linked list.
//
template <typename Item>
void list_head_insert(node<Item>*& head_ptr, const Item& entry)
{
head_ptr = new node<Item>(entry, head_ptr);
}
// list_head_remove
//
// preconditions: head_ptr is the head pointer of a linked list,
// with at least one node.
// postconditions: The head node has been removed and returned to
// the heap; head_ptr is now the head pointer of the new, shorter
// linked list.
//
template <typename Item>
void list_head_remove(node<Item>*& head_ptr)
{
node<Item> *remove_ptr;
remove_ptr = head_ptr;
head_ptr = head_ptr->get_next( );
delete remove_ptr;
}
// list_insert
//
// precondition: previous_ptr points to a node in a linked list.
// postconditions: A new node containing the given entry has been
// added after the node that previous_ptr points to.
//
template <typename Item>
void list_insert(node<Item>* previous_ptr, const Item& entry)
{
node<Item> *insert_ptr;
insert_ptr = new node<Item>(entry, previous_ptr->get_next( ));
previous_ptr->set_next(insert_ptr);
}
// list_length
//
// precondition: head_ptr is the head pointer of a linked list.
// postconditions: The value returned is the number of nodes in
// the linked list.
//
template <typename Item>
std::size_t list_length(const node<Item>* head_ptr)
{
const node<Item> *cursor;
std::size_t answer;
answer = 0;
for (cursor = head_ptr; cursor != NULL; cursor = cursor->get_next())
{
answer++;
}
return answer;
}