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.