//----------------------------------------------------------------------------- #include "linkedlistclass.h" #include //----------------------------------------------------------------------------- //----Public parts of linkedlistnode //----------------------------------------------------------------------------- //----Initial value constructor template linkedlistnode::linkedlistnode(const NodeType& NewNodeData) { Data = NewNodeData; NextNodePointer = NULL; PreviousNodePointer = NULL; } //----------------------------------------------------------------------------- //----Set and get node data template void linkedlistnode::SetNodeData(const NodeType& NewNodeData) { Data = NewNodeData; } //----------------------------------------------------------------------------- template NodeType linkedlistnode::GetNodeData(void) const { return(Data); } //----------------------------------------------------------------------------- //----Public parts of linkedlist //----------------------------------------------------------------------------- //----Default constructor template linkedlist::linkedlist(void) { FirstNodePointer = LastNodePointer = NULL; } //----------------------------------------------------------------------------- //----Copy constructor template linkedlist::linkedlist(const linkedlist& CopyThisList) { linkedlistnode *CurrentNodePointer; //----Start list as empty FirstNodePointer = LastNodePointer = NULL; //----Look through values in copy list, adding a node for each CurrentNodePointer = CopyThisList.FirstNodePointer; while (CurrentNodePointer != NULL) { AddAtEnd((*CurrentNodePointer).GetNodeData()); CurrentNodePointer = CurrentNodePointer->NextNodePointer; } } //----------------------------------------------------------------------------- //----Destructor template linkedlist::~linkedlist(void) { //----Move down to end of list deleting as we go while (!Empty()) DeleteOldNode(FirstNodePointer); } //----------------------------------------------------------------------------- //----Test if empty template boolean linkedlist::Empty(void) const { return(FirstNodePointer == NULL); } //----------------------------------------------------------------------------- //----Get data from first node template NodeType linkedlist::GetFirstNodeData(void) const { //----User is responsible for use, so die if they're stupid assert(!Empty()); return((*FirstNodePointer).GetNodeData()); } //----------------------------------------------------------------------------- //----Get data from last node template NodeType linkedlist::GetLastNodeData(void) const { //----User is responsible for use, so die if they're stupid assert(!Empty()); return((*LastNodePointer).GetNodeData()); } //----------------------------------------------------------------------------- //----Add node at start template void linkedlist::AddAtStart(const NodeType& NewNodeData) { linkedlistnode *NewNodePointer; //----Make a new node with the data NewNodePointer = MakeNewNode(NewNodeData); //----If the only node, then also the last node if (Empty()) FirstNodePointer = LastNodePointer = NewNodePointer; else { FirstNodePointer->PreviousNodePointer = NewNodePointer; NewNodePointer->NextNodePointer = FirstNodePointer; FirstNodePointer = NewNodePointer; } } //----------------------------------------------------------------------------- //----Add node at end template void linkedlist::AddAtEnd(const NodeType& NewNodeData) { linkedlistnode *NewNodePointer; //----Make a new node with the data NewNodePointer = MakeNewNode(NewNodeData); //----If empty then link as first and last if (Empty()) { FirstNodePointer = LastNodePointer = NewNodePointer; } //----Otherwise add as last with link else { LastNodePointer->NextNodePointer = NewNodePointer; NewNodePointer->PreviousNodePointer = LastNodePointer; LastNodePointer = NewNodePointer; } } //----------------------------------------------------------------------------- //----Delete from the start of the list if possible template void linkedlist::DeleteAtStart(void) { //----User is responsible for use, so die if they're stupid assert(!Empty()); DeleteOldNode(FirstNodePointer); } //----------------------------------------------------------------------------- //----Delete from the end of the list if possible template void linkedlist::DeleteAtEnd(void) { //----User is responsible for use, so die if they're stupid assert(!Empty()); DeleteOldNode(LastNodePointer); } //----------------------------------------------------------------------------- //----Dump for debugging template void linkedlist::Dump(void) const { linkedlistnode *CurrentNodePointer; cout << endl << "Forwards: "; CurrentNodePointer = FirstNodePointer; while (CurrentNodePointer != NULL) { cout << CurrentNodePointer->Data << " "; CurrentNodePointer = CurrentNodePointer->NextNodePointer; } cout << "Backwards: "; CurrentNodePointer = LastNodePointer; while (CurrentNodePointer != NULL) { cout << CurrentNodePointer->Data << " "; CurrentNodePointer = CurrentNodePointer->PreviousNodePointer; } cout << endl; } //----------------------------------------------------------------------------- //----Private parts of linkedlist //----------------------------------------------------------------------------- //----Function to make new nodes and check template linkedlistnode *linkedlist::MakeNewNode( const NodeType& NewNodeData) const { linkedlistnode *NewNodePointer; //----Claim memory (calling node constructor) and check for success NewNodePointer = new linkedlistnode(NewNodeData); assert(NewNodePointer != NULL); return(NewNodePointer); } //----------------------------------------------------------------------------- //----Function to delete a node and update the links template void linkedlist::DeleteOldNode( linkedlistnode *OldNodePointer) { //----Internal check for stupidity assert(OldNodePointer != NULL); //----Find where it is on the list if (OldNodePointer == FirstNodePointer) if (OldNodePointer == LastNodePointer) //----It's the only node FirstNodePointer = LastNodePointer = NULL; else { //----It's the first node and not last node FirstNodePointer = FirstNodePointer->NextNodePointer; FirstNodePointer->PreviousNodePointer = NULL; } else if (OldNodePointer == LastNodePointer) { //----It's the last node and not first node LastNodePointer = LastNodePointer->PreviousNodePointer; LastNodePointer->NextNodePointer = NULL; } else { //----It's in the middle somewhere OldNodePointer->PreviousNodePointer->NextNodePointer = OldNodePointer->NextNodePointer; OldNodePointer->NextNodePointer->PreviousNodePointer = OldNodePointer->PreviousNodePointer; } //----Free memory delete OldNodePointer; } //----------------------------------------------------------------------------- //----Public parts of linkedlistiterator //----------------------------------------------------------------------------- //----Constructor taking name of list template linkedlistiterator::linkedlistiterator( linkedlist& ListToIterate) { TheList = &ListToIterate; CurrentNodePointer = NULL; } //----------------------------------------------------------------------------- //----Checks if current and next are there template boolean linkedlistiterator::NodeExists(void) const { return(CurrentNodePointer != NULL); } //----------------------------------------------------------------------------- template boolean linkedlistiterator::NextNodeExists(void) const { //----User is responsible for use, so die if they're stupid assert(NodeExists()); return(CurrentNodePointer->NextNodePointer != NULL); } //----------------------------------------------------------------------------- template boolean linkedlistiterator::PreviousNodeExists(void) const { //----User is responsible for use, so die if they're stupid assert(NodeExists()); return(CurrentNodePointer->PreviousNodePointer != NULL); } //----------------------------------------------------------------------------- //----To the start of the linked list template void linkedlistiterator::ToStart(void) { CurrentNodePointer = TheList->FirstNodePointer; } //----------------------------------------------------------------------------- //----To the end of the linked list template void linkedlistiterator::ToEnd(void) { CurrentNodePointer = TheList->LastNodePointer; } //----------------------------------------------------------------------------- //----To the next node of the linked list template void linkedlistiterator::operator ++(void) { //----User is responsible for use, so die if they're stupid assert(NodeExists()); if (NextNodeExists()) CurrentNodePointer = CurrentNodePointer->NextNodePointer; else CurrentNodePointer = NULL; } //----------------------------------------------------------------------------- //----To the previous node of the linked list template void linkedlistiterator::operator --(void) { //----User is responsible for use, so die if they're stupid assert(NodeExists()); if (PreviousNodeExists()) CurrentNodePointer = CurrentNodePointer->PreviousNodePointer; else CurrentNodePointer = NULL; } //----------------------------------------------------------------------------- //----Set data of current template void linkedlistiterator::SetCurrentData(const NodeType& NewNodeData) { //----User is responsible for use, so die if they're stupid assert(NodeExists()); (*CurrentNodePointer).SetNodeData(NewNodeData); } //----------------------------------------------------------------------------- //----Return current node's data template NodeType linkedlistiterator::CurrentData(void) const { //----User is responsible for use, so die if they're stupid assert(NodeExists()); return((*CurrentNodePointer).GetNodeData()); } //----------------------------------------------------------------------------- //----Add node before current template void linkedlistiterator::AddBefore(const NodeType& NewNodeData) const { linkedlistnode *NewNodePointer; //----User is responsible for use, so die if they're stupid assert(NodeExists()); //----If nothing before, then it's at start if (!PreviousNodeExists()) (*TheList).AddAtStart(NewNodeData); //----Else make node and link in else { //----Make a new node with the data NewNodePointer = (*TheList).MakeNewNode(NewNodeData); NewNodePointer->NextNodePointer = CurrentNodePointer; NewNodePointer->PreviousNodePointer = CurrentNodePointer->PreviousNodePointer; NewNodePointer->PreviousNodePointer->NextNodePointer = NewNodePointer; CurrentNodePointer->PreviousNodePointer = NewNodePointer; } } //----------------------------------------------------------------------------- //----Add node after current template void linkedlistiterator::AddAfter(const NodeType& NewNodeData) const { linkedlistnode *NewNodePointer; //----User is responsible for use, so die if they're stupid assert(NodeExists()); //----If nothing before, then it's at start if (!NextNodeExists()) (*TheList).AddAtEnd(NewNodeData); //----Else make node and link in else { //----Make a new node with the data NewNodePointer = (*TheList).MakeNewNode(NewNodeData); NewNodePointer->NextNodePointer = CurrentNodePointer->NextNodePointer; NewNodePointer->PreviousNodePointer = CurrentNodePointer; NewNodePointer->NextNodePointer->PreviousNodePointer = NewNodePointer; CurrentNodePointer->NextNodePointer = NewNodePointer; } } //----------------------------------------------------------------------------- //----To delete here template void linkedlistiterator::DeleteCurrent(void) { //----User is responsible for use, so die if they're stupid assert(NodeExists()); (*TheList).DeleteOldNode(CurrentNodePointer); CurrentNodePointer = NULL; } //----------------------------------------------------------------------------- //----To delete next template void linkedlistiterator::DeleteNext(void) { //----User is responsible for use, so die if they're stupid assert(NextNodeExists()); (*TheList).DeleteOldNode(CurrentNodePointer->NextNodePointer); } //----------------------------------------------------------------------------- //----To delete previous template void linkedlistiterator::DeletePrevious(void) { //----User is responsible for use, so die if they're stupid assert(PreviousNodeExists()); (*TheList).DeleteOldNode(CurrentNodePointer->PreviousNodePointer); } //-----------------------------------------------------------------------------