/* 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 LinkedItem::LinkedItem() { Next = NULL; } template LinkedList::LinkedList() { Size = 0; Root = NULL; } template LinkedList::LinkedList(const LinkedList &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 *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; 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; 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 LinkedList::~LinkedList() { FreeMemory(); } template LinkedList& LinkedList::operator = (const LinkedList &LL) { //this is equivalent to initalization with LL, except we need to free our own memory first, if we have any FreeMemory(); LinkedItem *LLCurrent = LL.Root, *MyFinalNode = NULL; while(LLCurrent != NULL) { if(MyFinalNode == NULL) { MyFinalNode = new LinkedItem; Root = MyFinalNode; MyFinalNode->Next = NULL; MyFinalNode->Data = LLCurrent->Data; Size++; } else { MyFinalNode->Next = new LinkedItem; MyFinalNode->Next->Data = LLCurrent->Data; MyFinalNode = MyFinalNode->Next; Size++; } LLCurrent = LLCurrent->Next; } return *this; } template void LinkedList::FreeMemory() { if((Root) && (Size > 0)) //if we have any memory to free up { LinkedItem *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 type* LinkedList::Dump() { if(Size > 0) { LinkedItem *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 void LinkedList::Dump(Vector &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 *Stage=Root; for(int i = 0;i < Size;i++) { V[Size-i-1] = Stage->Data; Stage = Stage->Next; } } } template LinkedItem* LinkedList::GetPtr(int k) { //slow and inefficent, this function just starts at the root and progesses k times. LinkedItem* 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 void LinkedList::Remove(int i) { if(Size > 0) { if(i == 0) Pop(); else { LinkedItem *Prev = GetPtr(i-1); //store the (i-1)'th and the i'th, LinkedItem *ToDie = Prev->Next; Prev->Next = ToDie->Next; //and skip over the i'th Size--; delete ToDie; //free the i'th from memory } } } template type& LinkedList::operator [] (int k) { return GetPtr(k)->Data; } template void LinkedList::Push() { LinkedItem *Temp, *Store; Temp = new LinkedItem; Store = Root; Root = Temp; Root->Next = Store; Size++; } template void LinkedList::Pop() { if(Size > 0) { LinkedItem *Store = Root; Root = Root->Next; delete Store; Size--; if(Size == 0) Root = NULL; } } template void LinkedList::Pop(type &t) { t = (*this)[0]; Pop(); } template void LinkedList::Push(const type &t) { Push(); Root->Data = t; } #endif