/*
LinkedList.cpp
Written by Matthew Fisher
The LinkedList class contains linked lists of a template type. There is also a STL equivalent that I
choose not to use. Only the LinkedList class should be referenced directly. See LinkedList.h for a
complete definition of the Linked List class.
*/
#ifndef __LL_CPP
#define __LL_CPP
#include "LinkedList.h"
template <class type> LinkedItem<type>::LinkedItem()
{
Next = NULL;
}
template <class type> LinkedList<type>::LinkedList()
{
Size = 0;
Root = NULL;
}
template <class type> LinkedList<type>::LinkedList(const LinkedList<type> &LL)
{
//to initalize ourselves as the data in LL, we need to parse over all entries in LL,
//and copy each one into our own local data
Size = 0;
Root = NULL;
LinkedItem<type> *LLCurrent = LL.Root, //start at LL's root
*MyFinalNode = NULL; //we have no root node yet
while(LLCurrent != NULL)
{
if(MyFinalNode == NULL) //if this is the 1st element,
{
MyFinalNode = new LinkedItem<type>;
Root = MyFinalNode; //create a new root node for us
MyFinalNode->Next = NULL;
MyFinalNode->Data = LLCurrent->Data; //the data in the root node equals the data in LL's root node
Size++; //we're one element bigger now
} else {
MyFinalNode->Next = new LinkedItem<type>;
MyFinalNode->Next->Data = LLCurrent->Data;
MyFinalNode = MyFinalNode->Next; //add the current data/node in LL to our list
Size++;
}
LLCurrent = LLCurrent->Next; //go to the next element in LL
}
}
template <class type> LinkedList<type>::~LinkedList()
{
FreeMemory();
}
template <class type> LinkedList<type>& LinkedList<type>::operator = (const LinkedList<type> &LL)
{
//this is equivalent to initalization with LL, except we need to free our own memory first, if we have any
FreeMemory();
LinkedItem<type> *LLCurrent = LL.Root, *MyFinalNode = NULL;
while(LLCurrent != NULL)
{
if(MyFinalNode == NULL)
{
MyFinalNode = new LinkedItem<type>;
Root = MyFinalNode;
MyFinalNode->Next = NULL;
MyFinalNode->Data = LLCurrent->Data;
Size++;
} else {
MyFinalNode->Next = new LinkedItem<type>;
MyFinalNode->Next->Data = LLCurrent->Data;
MyFinalNode = MyFinalNode->Next;
Size++;
}
LLCurrent = LLCurrent->Next;
}
return *this;
}
template <class type> void LinkedList<type>::FreeMemory()
{
if((Root) && (Size > 0)) //if we have any memory to free up
{
LinkedItem<type> *Stage=Root,*ToDie;
for(int i = 0;i < Size;i++) //iterate through each element
{
ToDie = Stage;
Stage = Stage->Next; //go to the next element
delete ToDie; //delete the previous element
}
if(Stage) delete Stage;
}
Size = 0;
Root = NULL;
}
template <class type> type* LinkedList<type>::Dump()
{
if(Size > 0)
{
LinkedItem<type> *Stage=Root;
type *Dumped = new type[Size]; //allocate space for the dumped data
for(int i = 0;i < Size;i++) //iterate through each element
{
Dumped[Size-i-1] = Stage->Data; //load the current element into the array
Stage = Stage->Next; //go to the next element
}
return Dumped;
} else return NULL; //no data, so return a NULL pointer
}
template <class type> void LinkedList<type>::Dump(Vector<type> &V)
{
//this is the exact same as Dump() for a standard array, except we put our data into the vector V instead.
V.Allocate(Size);
if(Size > 0)
{
LinkedItem<type> *Stage=Root;
for(int i = 0;i < Size;i++)
{
V[Size-i-1] = Stage->Data;
Stage = Stage->Next;
}
}
}
template <class type> LinkedItem<type>* LinkedList<type>::GetPtr(int k)
{
//slow and inefficent, this function just starts at the root and progesses k times.
LinkedItem<type>* Stage=Root;
if(!Stage) return Stage;
if(k >= Size)
{ //normally I set a breakpoint here.
cout << "Out of bounds Linked List access; Index = " << k << ", Size = " << Size << endl;
exit(1);
}
for(int i = 0;i < k;i++)
Stage = Stage->Next;
return Stage;
}
template <class type> void LinkedList<type>::Remove(int i)
{
if(Size > 0)
{
if(i == 0) Pop();
else
{
LinkedItem<type> *Prev = GetPtr(i-1); //store the (i-1)'th and the i'th,
LinkedItem<type> *ToDie = Prev->Next;
Prev->Next = ToDie->Next; //and skip over the i'th
Size--;
delete ToDie; //free the i'th from memory
}
}
}
template <class type> type& LinkedList<type>::operator [] (int k)
{
return GetPtr(k)->Data;
}
template <class type> void LinkedList<type>::Push()
{
LinkedItem<type> *Temp, *Store;
Temp = new LinkedItem<type>;
Store = Root;
Root = Temp;
Root->Next = Store;
Size++;
}
template <class type> void LinkedList<type>::Pop()
{
if(Size > 0)
{
LinkedItem<type> *Store = Root;
Root = Root->Next;
delete Store;
Size--;
if(Size == 0) Root = NULL;
}
}
template <class type> void LinkedList<type>::Pop(type &t)
{
t = (*this)[0];
Pop();
}
template <class type> void LinkedList<type>::Push(const type &t)
{
Push();
Root->Data = t;
}
#endif
Top