#include <iostream>
using namespace std;
template <class Type>
struct nodeType
{
Type info;
nodeType<Type> *link;
};
template <class Type>
class linkedListIterator
{
public:
linkedListIterator(); //Default constructor
linkedListIterator(nodeType<Type> *p); //constructor
Type operator*(); //overload dereferencing operator * ie. *p=val
linkedListIterator<Type> operator++(); //overload the PREincrement operator
//POSTincrement would be linkedListIterator<Type> operator++(int);
bool operator==(const linkedListIterator<Type>& right) const;
//overload equality operator. second const is to make function itself const,
//because it doesn't modify the object
bool operator!=(const linkedListIterator<Type>& right) const;
//over not equal to operator. reference param must be const to prevent change.
private:
nodeType<Type> *current; //ptr points to current node in linked list
};//UML on page 281
template <class Type>
class linkedListType
{
public:
const linkedListType<Type>& operator=(const linkedListType<Type>&);
//overload the assignment operator
void initializeList(); //initialize list into an empty state
bool isEmptyList() const; //function to determine if list is empty,
//doesn't change list, so constant.
void print() const; //function to output data in each node
int length() const; //return number of nodes in list
void destroyList(); //delete all nodes from list, no const, because change
Type front() const; //return first element of list
Type back() const; //return last element of list
//to be derived functions-virtual =0 pure virtual, only overwritten
virtual bool search(const Type& searchItem) const = 0;// determine if item in list
virtual void insertFirst(const Type& newItem) = 0; //insert newitem at begin of list
virtual void insertLast(const Type& newItem) = 0; //insert newitem at end of list
virtual void deleteNode(const Type& deleteItem) = 0; //delete item from list
//returntype function make use of the linkedListIterator class?
linkedListIterator<Type> begin(); //return an iterator at beginning of linked list
linkedListIterator<Type> end(); //return iterator one element past last element of list
linkedListType(); //default constructor
linkedListType(const linkedListType<Type>& otherList); //argument constructor
~linkedListType(); //destructor
protected: //for use in class functions and derived classes/functions
int count; //number of list items
nodeType<Type> *first; //pointer to first node of list
nodeType<Type> *last; //pointer to last node of list
private:
void copyList(const linkedListType<Type>& otherList);
//function to make a copy of otherlist and assign to this list
};
template <class Type>
class unorderedLinkedList: public linkedListType<Type> //inherit public section of lLT class
{
public:
bool search(const Type& searchItem) const; //const on referenced item, const on function
//determines if item is in the list
void insertFirst(const Type& newItem); //insert newitem at beginning of list
void insertLast(const Type& newItem); //insert newitem at end of list
void deleteNode(const Type& deleteItem); //delete deleteItem from list
};
template <class Type> //default constructor
linkedListIterator<Type>::linkedListIterator()
{ //constructors don't need return type
current = NULL;
}
template <class Type> //argument constructor
linkedListIterator<Type>::linkedListIterator(nodeType<Type> *p)
{
current = p; //set current to pointer argument
}
template <class Type> //overload dereference operator
Type linkedListIterator<Type>::operator*() //return type template
{
return current->info;
}
template <class Type> //overload preincrement operator
linkedListIterator<Type> linkedListIterator<Type>::operator++()
{
current = current->link;
return *this;
}
template <class Type> //overload equality operator
bool linkedListIterator<Type>::operator==(const linkedListIterator<Type>& right) const
{
return (current == right.current); //compares both values
}
template <class Type> //overload not equal to operator
bool linkedListIterator<Type>::operator!=(const linkedListIterator<Type>& right) const
{
return (current != right.current);
}
template <class Type> //O(1)
bool linkedListType<Type>::isEmptyList() const
{
return (first == NULL); //if equal to NULL, then list empty
}
template <class Type>//O(1)
linkedListType<Type>::linkedListType() //Default constructor
{
first = NULL;
last = NULL;
count = 0; //create empty list
}
template <class Type>//O(n)
void linkedListType<Type>::destroyList() //deallocates memory occupied by nodes
{
nodeType<Type> *temp; //pointer to deallocate memory
while (first != NULL) //while there are nodes, loop
{
temp = first;
first = first->link; //move first onto next node to prevent losing place and
// ending up with dangling pointers/memory
delete temp; //deallocate memory in this node
}
last = NULL; //initialize last to NULL, while loop already set first to NULL
count = 0; //no more nodes..
}
template <class Type>//O(n)
void linkedListType<Type>::initializeList() //p287, reinitialize list to empty state, delete nodes
{
destroyList(); //if list has any nodes, delete them
}
template <class Type>//O(n)
void linkedListType<Type>::print() const
{
nodeType<Type> *current; //pointer to traverse list, if you use first, list will be lost
current = first;
while (current != NULL) //while more data to print, loop
{
cout << current->info << " ";
current = current->link; //next node
}
}
template <class Type>//O(1)
int linkedListType<Type>::length() const //return int count number
{
return count; //member var that counts amount of nodes in list
}
template <class Type>//O(1)
Type linkedListType<Type>::front() const //returns info in first node
{
assert(first != NULL); //if list NULL, assert terminates program
return first->info; //return info of first node
}
template <class Type>//O(1)
Type linkedListType<Type>::back() const // returns info in last node
{
assert(last != NULL); //term if NULL
return last->info;//info of last node
}
//iterators begin and end, for use in for loops?
template <class Type>//O(1)
//Type(iterator) memberclass::member
linkedListIterator<Type> linkedListType<Type>::begin() //begin iterator
{
linkedListIterator<Type> temp(first);
return temp;
}
template <class Type>//O(1)
//Type(iterator) memberclass::member
linkedListIterator<Type> linkedListType<Type>::end() //end iterator
{
linkedListIterator<Type> temp(NULL);
return temp;
}
//make deep copy of list
template <class Type>//O(n)
void linkedListType<Type>::copyList(const linkedListType<Type>& otherList)//const, don't want to change list
{ //create ptrs to be used
nodeType<Type> *newNode; //ptr to create a node
nodeType<Type> *current; //ptr to traverse list
if (first != NULL) //if list nonempty, then make it empty
destroyList();
if (otherList.first == NULL) //otherList is empty
{
first = NULL;
last = NULL;
count = 0;
}
else
{
current = otherList.first; //current points to list to be copied
count = otherList.count;
//copy first node-head
first = new nodeType<Type>; //create node
first->info = current->info; //copy info
first->link = NULL; //set the link field of node to NULL
last = first; //make last point to first
current = current->link; //point current to next node
//copy remaining list
while (current != NULL)
{
newNode = new nodeType<Type>; //create node
newNode->info = current->info; //copy info
newNode->link = NULL; //set link of newNode to NULL
last->link = newNode; //attach newnode after last
last = newNode; //make last point to actual last
current = current->link; //point current to next node
}
}
}
template <class Type>//O(n)
linkedListType<Type>::~linkedListType() //destructor
{
destroyList();
}
template<class Type>//O(n)
linkedListType<Type>::linkedListType(const linkedListType<Type>& otherList) //copy constructor
{
first = NULL; //must be NULL to use copyList
copyList(otherList);
}
template <class Type>//O(n)
const linkedListType<Type>& linkedListType<Type>::operator=(const linkedListType<Type>& otherList)
//overloaded assignment operator
{
if (this != &otherList) //avoid self-copy
{
copyList(otherList);
}
return *this; //return value of this pointer
}
template <class Type>//O(n)
bool unorderedLinkedList<Type>::search(const Type& searchItem) const
{ //search for item then return true if found
nodeType<Type> *current; //create pointer to traverse list
bool found = false; //loop controll variable, if true stop
current = first; //current points to first node in list
while (current != NULL && !found) //repeat until end of list, and found is true
//above will keep looping while found is not true, the moment found is true,
//i.e. opposite of !found, it will stop the loop.
if (current->info == searchItem) //searchItem is found
found = true;
else
current = current->link; //point current to next node, move through list
return found;
}
template <class Type>//O(1)
void unorderedLinkedList<Type>::insertFirst(const Type& newItem)
{
nodeType<Type> *newNode; //pointer to create the new node
newNode = new nodeType<Type>; //allocate memory for and create node
newNode->info = newItem; //store new item inside new node
newNode->link = first; //insert newnode before first
first = newNode; //make first point to actual first node
count++; //increment count, size of list
if (last == NULL)
last = newNode; //if list was empty, set last to point to newnode as last
}
template <class Type>//O(1)
void unorderedLinkedList<Type>::insertLast(const Type& newItem)
{
nodeType<Type> *newNode; //pointer to create new node
newNode = new nodeType<Type>; //allocate new memory for node and create it
newNode->info = newItem; //store new item in the node
newNode->link = NULL; //set link of newnode to NULL, it's at end of list after all
if (first == NULL) //if the list is empty, newNode is both first and last node
{
first = newNode;
last = newNode;
count++; //increment size/counter of list
}
else //list not empty, insert newnode after last
{
last->link = newNode; //insert newNode after last
last = newNode; //make last point to actual last node in list
count++; //increment list size count
}
}
int main()
{
cout << "Hello world!" << endl;
return 0;
}//UML on page 285