// simplified Account List class // // Based on simplified List Template Class // described in Chapter 9 of // Data Structures in C++ using the STL // // // MAR 4/4/00 - avoided templates // #include #include "Account-new.h" #include "AcctListNode.h" #include "AcctListList.h" // default constructor AcctList::AcctList () { // no connections currSize = 0; firstLink = 0; lastLink = 0; } // copy constructor - copies whole list AcctList::AcctList (AcctList & toCopy) { // start with an empty list lastLink = 0; firstLink = 0; // loop through the list copying each account in turn // and allocating storage and building the list for (AcctNode * ptr = toCopy.firstLink; ptr != 0; ptr = ptr->NextNode()) { // create a copy of the Account to be copied // not sure why we don't have to allocate storage using new Account newEl(ptr->GetValue() ); // push the copy onto the new list being created push_back(newEl); } currSize = toCopy.size(); } // destructor - gives back any storage when list goes away AcctList::~AcctList() { AcctNode * firstPtr = firstLink; // loop until there are no more elements in the list while (firstPtr != 0) { // save a pointer to past element being deleted so we don't // lose our place AcctNode * next = firstPtr->NextNode(); // give storage back delete firstPtr; // continue with the next element in the list firstPtr = next; } } /////////////////// // list operations /////////////////// ////// // inspectors ////// // reports whether the list is empty or not bool AcctList::empty() { // could also do by seeing if currSize == 0 if (firstLink == 0) { return true; } else { return false; } } // reports current list size int AcctList::size() { return currSize; } // show whole list in order void AcctList::ShowList() { AcctNode * acctPtr = firstLink; // loop until there are no more elements in the list while (acctPtr != 0) { // display the element cout << *acctPtr << endl; // move to the next element acctPtr = acctPtr->NextNode(); } return; } ////// // not exactly inspectors, since making element available ////// // reports first Account in List Account & AcctList::front() { return firstLink->GetValue(); } // reports last Account in List Account & AcctList::back() { return lastLink->GetValue(); } // reports pointer to first Node in List AcctNode * AcctList::begin() { return firstLink; } // reports pointer to last Node in List AcctNode * AcctList::end() { return lastLink; } ////// // mutators ////// // add an element to the front of the list void AcctList::push_front(Account & newOne) { // create a new node for the passed account AcctNode * newLink = new AcctNode(newOne); // see if the list is empty if (empty()) { // link the new element into the list as both first and last element lastLink = newLink; firstLink = newLink; } else { // there is at least one element // link in before the first one firstLink->prevLink = newLink; // point back from previous first node newLink->nextLink = firstLink; // point forward from the new node firstLink = newLink; // set ptr to new head of list } currSize++; return; } // add an element to the back of the list void AcctList::push_back(Account & newOne){ // create a new node for the passed account AcctNode * newLink = new AcctNode(newOne); // see if the list is empty if (empty()) { // link the new element into the list as both first and last element lastLink = newLink; firstLink = newLink; } else { // there is at least one element // link in after the last one lastLink->nextLink = newLink; // point back from previous last node newLink->prevLink = lastLink; // point backward from the new node lastLink = newLink; // set ptr to new end of list } currSize++; return; } // remove the front element from the list void AcctList::pop_front() { // if list is empty cannot get rid of an element if (empty()) { return; } else { // save a pointer to the element to be deleted AcctNode * savePtr = firstLink; // point the start of the list to the second element firstLink = firstLink->NextNode(); // if there is no second element - set end of list to null // if there is a second element set its previous link to null if (firstLink == 0) { lastLink = 0; } else { firstLink->prevLink = 0; } // get rid of the record delete savePtr; } currSize--; return; } // remove the back element from the list void AcctList::pop_back(){ // if list is empty cannot get rid of an element if (empty()) { return; } else { // there is at least one element so can delete // save a pointer to the element to be deleted AcctNode * savePtr = lastLink; // point the end of the list to the next to last element lastLink = lastLink->PrevNode(); // if there is no next to last element - set start of list to null if (lastLink == 0) { firstLink = 0; } else { // there is a next to last element - set its next link to null lastLink->nextLink = 0; } // get rid of the record delete savePtr; } currSize--; return; } // insert an element at a particular place in a list - before the placePtr void AcctList::insert (AcctNode * placePtr, Account & toAdd) { // create a new node for the passed account AcctNode * newLink = new AcctNode(toAdd); // point new element to acct to be placed before newLink->nextLink = placePtr; // point new element back to whatever was before newLink->prevLink = placePtr->PrevNode(); // have existing element poiint back to the new element placePtr->prevLink = newLink; // find element that is before the new one and point forward from it AcctNode * beforePtr = newLink->PrevNode(); if (beforePtr != 0) { beforePtr->nextLink = newLink; } currSize++; return; } // erase one element from a list (pointed to by param) void AcctList::erase (AcctNode * toErasePtr) { // do the job by calling the other erase - with the next element as the after end element erase(toErasePtr, toErasePtr->NextNode() ); return; } // erase a range of elements from a list // first param is a pointer to the first element to be deleted // second param is a pointer to the first element tot to be deleted // (the first element after the last one to be deleted) void AcctList::erase (AcctNode * startPtr, AcctNode * keepPtr) { //AcctNode * firstPtr = startPtr; // keep track of node before those being deleted AcctNode * prevPtr = startPtr->prevLink; //AcctNode * lastPtr = keepPtr; // see if removing initial part of list if (prevPtr == 0) { // now beginning of the list is the node after those being deleted firstLink = keepPtr; // see if list is now empty if (keepPtr == 0) { lastLink = 0; } else { // there are real elements // have the first of remaining have a null previous keepPtr->prevLink = 0; } } else { // not removing from the front of the list // have the last element before those being deleted point // to the first node after those being deleted prevPtr->nextLink = keepPtr; // see if removing all the way to the end if (keepPtr == 0) { // have end of list be the last element before those deleted lastLink = prevPtr; } else { // not removing all of the way to the end // have first element after deleted point back to last // element before deleted keepPtr->prevLink = prevPtr; } } // now actually delete the values while (startPtr != keepPtr) { AcctNode * nextPtr = startPtr; // point after the node being deleted so we don't lose our place nextPtr = nextPtr->NextNode(); // get rid of the node delete startPtr; // bump to the next node startPtr = nextPtr; // decrease the list size currSize--; } return; }