In: Computer Science
Working with Linked Lists in C++
Tasks
As stated in the objectives, you have two methods to implement. These methods (which contain TODO comments) are found in linked_list.cpp.
Part 1
Implement the copy constructor; use the LinkedBag as inspiration for your solution as the technique of creating a deep copy is essentially the same.
Part 2
Implement the replace method.
//linked_list.cpp
#include "linked_list.h"  // Header file
#include <cassert>
template<class Object>
LinkedList<Object>::LinkedList()
        : headPtr( nullptr ), itemCount( 0 )
{
}  // end default constructor
template<class Object>
LinkedList<Object>::LinkedList(const LinkedList<Object>& aList)
        : itemCount( aList.itemCount )
{
    // TODO: Implement me
}  // end copy constructor
template<class Object>
LinkedList<Object>::~LinkedList()
{
    clear();
}  // end destructor
template<class Object>
bool LinkedList<Object>::isEmpty() const
{
    return itemCount == 0;
}  // end isEmpty
template<class Object>
int LinkedList<Object>::getLength() const
{
    return itemCount;
}  // end getLength
template<class Object>
bool LinkedList<Object>::insert(int newPosition, const Object& newEntry)
{
    bool ableToInsert = (newPosition >= 1) && (newPosition <= itemCount + 1);
    if (ableToInsert)
    {
        // Create a new node containing the new entry
        auto newNodePtr = new Node<Object>( newEntry );
        // Attach new node to chain
        if (newPosition == 1)
        {
            // Insert new node at beginning of chain
            newNodePtr->setNext( headPtr );
            headPtr = newNodePtr;
        }
        else
        {
            // Find node that will be before new node
            Node<Object>* prevPtr = getNodeAt( newPosition - 1 );
            // Insert new node after node to which prevPtr points
            newNodePtr->setNext( prevPtr->getNext());
            prevPtr->setNext( newNodePtr );
        }  // end if
        itemCount++;  // Increase count of entries
    }  // end if
    return ableToInsert;
}  // end insert
template<class Object>
bool LinkedList<Object>::remove(int position)
{
    bool ableToRemove = (position >= 1) && (position <= itemCount);
    if (ableToRemove)
    {
        Node<Object>* curPtr = nullptr;
        if (position == 1)
        {
            // Remove the first node in the chain
            curPtr = headPtr; // Save pointer to node
            headPtr = headPtr->getNext();
        }
        else
        {
            // Find node that is before the one to delete
            Node<Object>* prevPtr = getNodeAt( position - 1 );
            // Point to node to delete
            curPtr = prevPtr->getNext();
            // Disconnect indicated node from chain by connecting the
            // prior node with the one after
            prevPtr->setNext( curPtr->getNext());
        }  // end if
        // Return node to system
        curPtr->setNext( nullptr );
        delete curPtr;
        curPtr = nullptr;
        itemCount--;  // Decrease count of entries
    }  // end if
    return ableToRemove;
}  // end remove
template<class Object>
void LinkedList<Object>::clear()
{
    while (!isEmpty())
        remove( 1 );
}  // end clear
template<class Object>
Object LinkedList<Object>::getEntry(int position) const noexcept( false )
{
    // Enforce precondition
    bool ableToGet = (position >= 1) && (position <= itemCount);
    if (ableToGet)
    {
        Node<Object>* nodePtr = getNodeAt( position );
        return nodePtr->getItem();
    }
    else
    {
        std::string message = "getEntry() called with an empty list or ";
        message = message + "invalid position.";
        throw (PrecondViolatedExcep( message ));
    }  // end if
}  // end getEntry
template<class Object>
void LinkedList<Object>::replace(int position, const Object& newEntry) noexcept( false )
{
    // TODO: Implement me; throw a PrecondViolatedExcep if preconditions aren't met
}  // end replace
template<class Object>
Node<Object>* LinkedList<Object>::getNodeAt(int position) const noexcept( false )
{
    // Check preconditions
    if ((position < 1) || (position > itemCount))
    {
        std::string message = "private helper method called with an invalid position";
        throw (PrecondViolatedExcep( message ));
    }
    // Count from the beginning of the chain
    Node<Object>* curPtr = headPtr;
    for (int skip = 1; skip < position; skip++)
    {
        curPtr = curPtr->getNext();
    }
    return curPtr;
}  // end getNodeAt
//  End of implementation file.
#include "linked_list.h" // Header file
#include <cassert>
template<class Object>
LinkedList<Object>::LinkedList()
: headPtr( nullptr ), itemCount( 0 )
{
} // end default constructor
template<class Object>
LinkedList<Object>::LinkedList(const
LinkedList<Object>& aList)
: itemCount( aList.itemCount )
{
   // initialize headPtr to null
headPtr = nullptr;
  
   // set listCurPtr to head node of aList
   Node<Object>* listCurPtr = aList.headPtr;
  
   // set curPtr to head node of this list
   Node<Object>* curPtr = headPtr;
  
   // loop over the aList
   while(listCurPtr != nullptr)
   {
       // create a new node with item from
listCurPtr
       Node<Object>* node = new
Node<Object>(listCurPtr->getItem());
      
       // headPtr is null, set node to
headPtr
       if(headPtr == nullptr)
       {
           headPtr =
node;
           curPtr =
headPtr; // set curr to headPtr
       }
       else // headPtr is not null
       {
          
curPtr->setNext(node); // set next of curPtr to node
           curPtr =
curPtr->getNext(); // move curPtr to the newly inserted
node
       }
      
       // move listCurPtr to next
node
       listCurPtr =
listCurPtr->getNext();
   }
  
} // end copy constructor
template<class Object>
LinkedList<Object>::~LinkedList()
{
clear();
} // end destructor
template<class Object>
bool LinkedList<Object>::isEmpty() const
{
return itemCount == 0;
} // end isEmpty
template<class Object>
int LinkedList<Object>::getLength() const
{
return itemCount;
} // end getLength
template<class Object>
bool LinkedList<Object>::insert(int newPosition, const
Object& newEntry)
{
bool ableToInsert = (newPosition >= 1) && (newPosition
<= itemCount + 1);
if (ableToInsert)
{
// Create a new node containing the new entry
auto newNodePtr = new Node<Object>( newEntry );
// Attach new node to chain
if (newPosition == 1)
{
// Insert new node at beginning of chain
newNodePtr->setNext( headPtr );
headPtr = newNodePtr;
}
else
{
// Find node that will be before new node
Node<Object>* prevPtr = getNodeAt( newPosition - 1 );
// Insert new node after node to which prevPtr points
newNodePtr->setNext( prevPtr->getNext());
prevPtr->setNext( newNodePtr );
} // end if
itemCount++; // Increase count of entries
} // end if
return ableToInsert;
} // end insert
template<class Object>
bool LinkedList<Object>::remove(int position)
{
bool ableToRemove = (position >= 1) && (position <=
itemCount);
if (ableToRemove)
{
Node<Object>* curPtr = nullptr;
if (position == 1)
{
// Remove the first node in the chain
curPtr = headPtr; // Save pointer to node
headPtr = headPtr->getNext();
}
else
{
// Find node that is before the one to delete
Node<Object>* prevPtr = getNodeAt( position - 1 );
// Point to node to delete
curPtr = prevPtr->getNext();
// Disconnect indicated node from chain by connecting the
// prior node with the one after
prevPtr->setNext( curPtr->getNext());
} // end if
// Return node to system
curPtr->setNext( nullptr );
delete curPtr;
curPtr = nullptr;
itemCount--; // Decrease count of entries
} // end if
return ableToRemove;
} // end remove
template<class Object>
void LinkedList<Object>::clear()
{
while (!isEmpty())
remove( 1 );
} // end clear
template<class Object>
Object LinkedList<Object>::getEntry(int position) const
noexcept( false )
{
// Enforce precondition
bool ableToGet = (position >= 1) && (position <=
itemCount);
if (ableToGet)
{
Node<Object>* nodePtr = getNodeAt( position );
return nodePtr->getItem();
}
else
{
std::string message = "getEntry() called with an empty list or
";
message = message + "invalid position.";
throw (PrecondViolatedExcep( message ));
} // end if
} // end getEntry
template<class Object>
void LinkedList<Object>::replace(int position, const
Object& newEntry) noexcept( false )
{
   // invalid position, throw PrecondViolatedExcep
if(position < 1 || position > itemCount)
   {
       std::string message = "replace()
called with an invalid position";
       throw (PrecondViolatedExcep(
message ));
   }
   // get the node at position
   Node<Object>* nodePtr =
getNodeAt(position);
  
   // update the item of nodePtr to newEntry
   nodePtr->setItem(newEntry); // assuming Node class
contains a method setItem to update the item of the
node  
      
} // end replace
template<class Object>
Node<Object>* LinkedList<Object>::getNodeAt(int
position) const noexcept( false )
{
// Check preconditions
if ((position < 1) || (position > itemCount))
{
std::string message = "private helper method called with an invalid
position";
throw (PrecondViolatedExcep( message ));
}
// Count from the beginning of the chain
Node<Object>* curPtr = headPtr;
for (int skip = 1; skip < position; skip++)
{
curPtr = curPtr->getNext();
}
return curPtr;
} // end getNodeAt
// End of implementation file.