// // // simplified Account list class // // Based on Simplified List Template Class // Described in Chapter 9 of // Data Structures in C++ using the STL // Published by Addison-Wesley, 1997 // Written by Tim Budd, budd@cs.orst.edu // Oregon State University // // // MAR 4/4/00 - Avoided templates because couldn't get // Budd's code to compile under Microsoft Visual Studio v6.0 #include "Account.h" #include "AccountListLink.h" #include "AccountListList.h" // copy constructor - I think this should create a copy of the input // list as the real list library does AccountList::AccountList (AccountList & toCopy) { // start with empty list lastLink = 0; firstLink = 0; // loop through the list copying each account in turn and allocating // storage and building the list for (AccountLink * ptr = toCopy.firstLink; ptr != 0; ptr = ptr->nextLink) { // create a copy of the Account to be copied Account newEl(ptr->GetValue() ); // push the copy onto the new list being created push_back(newEl); } } int AccountList::size () // count number of elements in collection { int counter = 0; for (AccountLink * ptr = firstLink; ptr != 0; ptr = ptr->nextLink) counter++; return counter; } void AccountList::ShowList () { // MAR 4/4/00 - show list in order int counter = 0; for (AccountLink * ptr = firstLink; ptr != 0; ptr = ptr->nextLink) { cout << *ptr << endl; } return; } void AccountList::push_front (Account & newValue) // add a new value to the front of a list { AccountLink * newLink = new AccountLink (newValue); if (empty()) { lastLink = newLink; firstLink = newLink; } else { firstLink->prevLink = newLink; newLink->nextLink = firstLink; firstLink = newLink; } } // MAR 4/4/00 - add a new value to the back of a list void AccountList::push_back (Account & newValue) { // create a new node (link in Budd jargon) containing the account AccountLink * newLink = new AccountLink (newValue); // if the list is empty, the new node is both first and last if (empty()) { lastLink = newLink; firstLink = newLink; } // otherwise stick on end else { // last previous one now points on to new one lastLink->nextLink = newLink; // new one points back to previous last one newLink->prevLink = lastLink; // now the last element in the list is the one just added lastLink = newLink; } } void AccountList::pop_front() // remove first element from linked list { if (firstLink == 0) { return; } else { AccountLink * save = firstLink; firstLink = firstLink->nextLink; if (firstLink != 0) firstLink->prevLink = 0; else lastLink = 0; delete save; } } // MAR 4/4/00 - remove last element from linked list void AccountList::pop_back() { // make sure there is at least one element before trying to use it if (lastLink == 0) { return; } else { // there is at least one element - so can delete // keep point to account being removed so can still refer to it AccountLink * save = lastLink; // bump the pointer to the last element back to the previous one // (students: if hadn't done the first statement, now we would not // know where the one being removed was anymore) lastLink = lastLink->prevLink; // if the element being removed was not the only one then set the // new last element's next pointer to nothing if (lastLink != 0) lastLink->nextLink = 0; else // element removed was the only one - so don't have to do previous statement // instead make sure the pointer to the first element is set to nothing so // it will be correct firstLink = 0; // gave memory for the element being removed back to the operating system delete save; } } AccountList::~AccountList () // remove each element from the list { AccountLink * first = firstLink; while (first != 0) { AccountLink * next = first->nextLink; delete first; first = next; } } // MAR here iterator could be replaced by a pointer to a link void AccountList::insert (AccountLink * itr, Account & value) // insert a new element into the middle of a linked list { AccountLink * newLink = new AccountLink(value); //AccountLink * current = itr->currentLink; // would basically already have current passed as a param AccountLink * current = itr; newLink->nextLink = current; newLink->prevLink = current->prevLink; current->prevLink = newLink; current = newLink->prevLink; if (current != 0) current->nextLink = newLink; } // MAR here iterators replaced by a pointer to a link void AccountList::erase (AccountLink * start, AccountLink * stop) // remove values from the range of elements { // AccountLink * first = start.currentLink; AccountLink * first = start; AccountLink * prev = first->prevLink; // AccountLink * last = stop.currentLink; AccountLink * last = stop; if (prev == 0) { // removing initial portion of list firstLink = last; if (last == 0) lastLink = 0; else last->prevLink = 0; } else { prev->nextLink = last; if (last == 0) lastLink = prev; else last->prevLink = prev; } // now delete the values /* while (start != stop) { // MAR has to be changed without iterators listIterator next = start; ++next; delete start.currentLink; start = next; } */ while (start != stop) { AccountLink * next = start; next = next->nextLink; delete start; start = next; } }