Please send questions to st10@humboldt.edu .
/************************************************************/
/* ADAPTED FROM:                                            */
/* http://www.cs.colorado.edu/~main/chapter4/node1.h        */
/*                                                          */
/* Main and Savitch, "Data Structures and Other Objects     */
/*    using C++", 2nd edition, Addison-Wesley, Ch.5,        */
/*    p. 210 (mostly)                                       */
/************************************************************/

//---------------------------------------------------------------------
// File: node1.h
// Name: Michael Main, Walter Savitch
//       (adapted by Sharon M. Tuttle)
// last modified: 3-2-05
//
// Class name: node 
//
// Description: serves as the unit from which a singly-linked list
//    can be built.
//
//    Also included in this file are a collection of
//    useful list-manipulation functions, called the 
//    "linked list toolkit"
//
// DYNAMIC MEMORY USAGE by the node class and linked list toolkit:
//    If there is insufficient dynamic memory, then the
//       following functions throw bad_alloc:
//          the contructors, 
//          list_head_insert, list_insert, list_copy, list_piece
//
// NOTE: 
//    Some of the methods and functions have return value that is
//       a pointer to a node. Each of these functions 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*).
//---------------------------------------------------------------------

#ifndef NODE1_H
#define NODE1_H

#include <cstdlib>      // provides size_t and NULL
using namespace std;

class node
{
    public:
        /****************************************************/
        /* TYPEDEFS and MEMBER CONSTANTS                    */
        /****************************************************/

        // node::value_type is the data type of the data_field
        //    of the node. It may be of any of the C++ built-in
        //    types (int, char, etc.), or a class with a 
        //    default constructor, a copy constructor, an
        //    assignment operator, and a test for equality
        //    (x == y).
        //
        // (CHANGE to desired type...)
        //
        typedef double value_type;

        /*****************************************************/
        /* 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.
        //
        node( );

        // postcondition: creates a node with data_field set to
        //    init_data, and next_field set to NULL.
        //
        node(const value_type& init_data);

        // postcondition: create a node with data_field obtained from
        //    the default constructor of the value_type, and
        //    next_field set to init_next.
        //
        node(node* init_next);

        // postcondition: create a node with data_field set to
        //    init_data, and next_field set to init_next.
        //
        node(const value_type& init_data, node* init_next);

        /*************************************************************/
        /* ACCESSORS and other constant member functions (observers) */
        /*************************************************************/

        // postcondition: returns the data from this node
        //
        value_type get_data( ) const;
   
        // 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.)
        //
        const node* get_next( ) const;
        node* get_next( );

        /*****************************************************/
        /* MODIFIERS and other modifying member functions    */
        /*****************************************************/

        // postcondition: the node now contains the specified
        //    new_data.
        //
        void set_data(const value_type& new_data);

        // postcondition: the node now contains the specified
        //    new_next pointer.
        //
        void set_next(node* new_next);

    private:

        /*****************************************************/
        /* DATA FIELDS                                       */
        /*****************************************************/

        value_type data_field;
        node*      next_field;
};

/****************************************************/
/* NONMEMBER FUNCTIONS for the node class           */
/****************************************************/

//----------------------------------------------
// HERE, these are functions for the so-called 
//    LINKED LIST TOOLKIT.
//----------------------------------------------

//---------------------------------------------------------------------
// function: list_length
//
// preconditions: head_ptr is the head pointer of a linked list
//
// postconditions: the value returned in the number of nodes in
//    the linked list
//
// Examples: if node* begin_ptr is the first node in a linked list of
//    3 nodes, then:
//       list_length(begin_ptr) == 3
//    if node* empty_ptr = NULL,
//       list_length(empty_ptr) == 0
//    
size_t list_length(const node* head_ptr);

//---------------------------------------------------------------------
// function: list_head_insert
//
// preconditions: 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
//
// Examples: if node* begin_ptr points to a list containing 8 2 7,
//    and value_type is int,
//    then list_head_insert(begin_ptr, 5)
//       results in a list containing 5 8 2 7;
//       that is, begin_ptr->get_data( ) == 5,
//                list_length(begin_ptr) == 4    
//    if node* empty_ptr = NULL, 
//    then list_head_insert(empty_ptr, 5)
//       results in a list containing 5;
//       that is, empty_ptr->get_data( ) == 5,
//                list_length(empty_ptr) == 1
//
void list_head_insert(node*& head_ptr, const node::value_type& entry);

//---------------------------------------------------------------------
// function: list_insert
//
// preconditions: 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.
//
// Examples: if you have a linked list 8 5 2 7,
//    and prev_ptr points to the node containing 8, 
//       then list_insert(prev_ptr, 9) results in the list 8 9 5 2 7,
//       and prev_ptr->get_next()->get_data() == 9;
//    if prev_ptr2 points to the node containing 7, 
//       then list_insert(prev_ptr2, 6) results in the list 8 9 5 2 7 6,
//       and prev_ptr->get_next()->get_data() == 6;
//    if prev_ptr3 points to the node containing 5, 
//       then list_insert(prev_ptr3, 4) results in the list 8 9 5 4 2 7 6,
//       and prev_ptr->get_next()->get_data() == 4;
//
void list_insert(node* previous_ptr, const node::value_type& entry);

//---------------------------------------------------------------------
// function: list_search
//    (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.)
//    
// preconditions: head_ptr is the head pointer of a linked list
//
// postconditions: the pointer returned points to the first node containing
//    the specified target in its data member. If there is no such node,
//    the NULL pointer is returned.
//
// Examples: for the linked list containing 8 5 2 7 8 10,
//    assuming that node* begin_ptr points to its head, and
//    assuming that node* result_ptr,
//    if result_ptr = list_search(begin_ptr, 8),
//        then result_ptr->get_data() == 8
//    if result_ptr = list_search(begin_ptr, 10),
//        then result_ptr->get_data() == 10
//    if result_ptr = list_search(begin_ptr, 2),
//        then result_ptr->get_data() == 2
//    if result_ptr = list_search(begin_ptr, 13),
//        then result_ptr == NULL
//
node* list_search(node* head_ptr, const node::value_type& target);

const node* list_search(const node* head_ptr, 
                        const node::value_type& target);

//---------------------------------------------------------------------
// function: list_locate
//    (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.)
//
// preconditions: 
//    *   head_ptr is the head pointer of a linked list
//    *   position > 0
//
// postconditions:
//    *   The pointer returned points to the node at the specified
//        position in the list. (The head node is position 1, the next node
//        is position 2, and so on.)
//    *   If there is no such position, then the NULL pointer is returned.
//
// Examples: for the linked list containing 8 5 2 7 8 10,
//    assuming that node* begin_ptr points to its head, and
//    assuming that node* result_ptr,
//    if result_ptr = list_search(begin_ptr, 1),
//        then result_ptr->get_data() == 8
//    if result_ptr = list_search(begin_ptr, 6),
//        then result_ptr->get_data() == 10
//    if result_ptr = list_search(begin_ptr, 3),
//        then result_ptr->get_data() == 2
//    if result_ptr = list_search(begin_ptr, 13),
//        then result_ptr == NULL
//    
// Library facilities used: 
//
node* list_locate(node* head_ptr, size_t position);

const node* list_locate(const node* head_ptr, size_t position);

//---------------------------------------------------------------------
// function: 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
//
// Examples: for the linked list containing 8 5 2 7,
//    assuming that node* begin_ptr points to its head,
//       then list_head_remove(begin_ptr) results in the linked
//          list 5 2 7,
//       and list_length(begin_ptr) == 3,
//       and begin_ptr->get_data() == 5.
//    for the linked list containing 13,
//    assuming that begin_ptr2 points to its head,
//       then list_head_remove(begin_ptr2) results in an empty list,
//       and list_length(begin_ptr) == 0,
//       and begin_ptr == NULL
//
void list_head_remove(node*& head_ptr);

//---------------------------------------------------------------------
// function: list_remove
//
// preconditions: previous_ptr points to a node in a linked list, and this
//    is NOT the tail node of the list.
//
// postconditions: The node *after* previous_ptr has been removed from
//    the linked list.
//
// Examples: for the linked list containing 8 5 2 7 8 10,
//    assuming that node* begin_ptr points to its head,
//       then list_remove(begin_ptr) results in the linked
//          list 8 2 7 8 10,
//       and list_length(begin_ptr) == 5,
//       and begin_ptr->get_next()->get_data() == 2;
//    for the linked list containing 8 2 7 8 10,
//    assuming that prev_ptr2 points to the node containing 7,
//    and begin_ptr points to its head,
//       then list_remove(prev_ptr2) results in the list 8 2 7 10,
//       and list_length(begin_ptr) == 4,
//       and prev_ptr2->get_next()->get_data() == 10;
//    for the linked list containing 8 2 7 10,    
//    assuming that prev_ptr2 points to the node containing 7,
//    and begin_ptr points to its head,
//       then list_remove(prev_ptr2) results in the list 8 2 7,
//       and list_length(begin_ptr) == 3,
//       and prev_ptr2->get_next() == NULL.
//
void list_remove(node* previous_ptr);

//---------------------------------------------------------------------
// function: list_clear
//
// preconditions: head_ptr is the head pointer of a linked list.
//
// postconditions: 
//    *   all nodes of the list have been returned to the heap;
//    *   head_ptr is now NULL
//
// Examples: for the linked list containing 8 5 2 7 8 10,
//    assuming that node* begin_ptr points to its head,
//       then list_clear(begin_ptr) results in an empty linked list,
//       and list_length(begin_ptr) == 0,
//       and begin_ptr == NULL.
//    for an empty linked list,
//    assuming that node* begin_ptr2 == NULL,
//       then list_clear(begin_ptr2) results in an empty linked list,
//       and list_length(begin_ptr2) == 0,
//       and begin_ptr2 == NULL.
//    
void list_clear(node*& head_ptr);

//---------------------------------------------------------------------
// function: list_copy
//
// preconditions: source_ptr is the head_ptr of a linked list
//      
// postconditions:
//    *   head_ptr and tail_ptr are the head and tail pointers for a
//        a new list that contains the same items as the list pointed
//        to by source_ptr.
//    *   the original list is unaltered.
//
// Examples: for the linked list containing 8 5 2 7,
//    assuming that node* begin_ptr points to its head,
//    and node* new_head, node* new_tail have been declared,
//       then list_copy(begin_ptr, new_head, new_tail) results in 
//          a new linked list copy containing 8 5 2 7,
//       and list_length(new_head) == 4,
//       and new_head->get_data() == 8,
//       and new_tail->get_data() == 7;
//    for an empty linked list,
//    assuming that node* begin_ptr2 == NULL,
//    and node* new_head2, node* new_tail2 have been declared,
//       then list_copy(begin_ptr2, new_head2, new_tail2) results in 
//          a new empty linked list,
//       and list_length(begin_ptr2) == 0,
//       and new_head2 == NULL,
//       and new_tail2 == NULL;
//    for a linked list containing 13,
//    assuming that node* begin_ptr3 points to the beginning of this list,
//    and node* new_head3, node* new_tail3 have been declared,
//       then list_copy(begin_ptr3, new_head3, new_tail3) results in
//          a new linked list containing 13,
//       and list_length(begin_ptr3) == 1,
//       and new_head3->get_data() = 13, 
//       and new_tail3->get_data() = 13;
//    
void list_copy(const node* source_ptr, 
               node*& head_ptr, node*& tail_ptr);

#endif