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