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_get_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;
}