Source of LinkedList.cpp


  1: // The copy constructor and the method setEntry are left as exercises.
  2: // ===================================================================

  4: //  Created by Frank M. Carrano and Tim Henry.
  5: //  Copyright (c) 2013 __Pearson Education__. All rights reserved.

  7: /** Implementation file for the class LinkedList.
  8:  @file LinkedList.cpp */

 10: #include "LinkedList.h"  // Header file
 11: #include <cassert>
 12:   
 13: template<class ItemType>
 14: LinkedList<ItemType>::LinkedList() : headPtr(nullptr), itemCount(0)
 15: {
 16: }  // end default constructor

 18: template<class ItemType>
 19: LinkedList<ItemType>::~LinkedList()
 20: {
 21:    clear();
 22: }  // end destructor

 24: template<class ItemType>
 25: bool LinkedList<ItemType>::isEmpty() const
 26: {
 27:    return itemCount == 0;
 28: }  // end isEmpty

 30: template<class ItemType>
 31: int LinkedList<ItemType>::getLength() const
 32: {
 33:    return itemCount;
 34: }  // end getLength

 36: template<class ItemType>
 37: bool LinkedList<ItemType>::insert(int newPosition, const ItemType& newEntry)
 38: {
 39:    bool ableToInsert = (newPosition >= 1) && (newPosition <= itemCount + 1);
 40:    if (ableToInsert)
 41:    {
 42:       // Create a new node containing the new entry
 43:       Node<ItemType>* newNodePtr = new Node<ItemType>(newEntry);
 44:       headPtr = insertNode(newPosition, newNodePtr, headPtr);
 45:    }  // end if
 46:    
 47:    return ableToInsert;
 48: }  // end insert

 50: template<class ItemType>
 51: bool LinkedList<ItemType>::remove(int position)
 52: {
 53:    bool ableToRemove = (position >= 1) && (position <= itemCount);
 54:    if (ableToRemove)
 55:    {
 56:       Node<ItemType>* curPtr = nullptr;
 57:       if (position == 1)
 58:       {
 59:          // Remove the first node in the chain
 60:          curPtr = headPtr; // Save pointer to node
 61:          headPtr = headPtr->getNext();
 62:       }
 63:       else
 64:       {
 65:          // Find node that is before the one to delete
 66:          Node<ItemType>* prevPtr = getNodeAt(position - 1);
 67:          
 68:          // Point to node to delete
 69:          curPtr = prevPtr->getNext();
 70:          
 71:          // Disconnect indicated node from chain by connecting the
 72:          // prior node with the one after
 73:          prevPtr->setNext(curPtr->getNext());
 74:       }  // end if
 75:       
 76:       // Return node to system
 77:       curPtr->setNext(nullptr);
 78:       delete curPtr;
 79:       curPtr = nullptr;
 80:       
 81:       itemCount--;  // Decrease count of entries
 82:    }  // end if
 83:    
 84:    return ableToRemove;
 85: }  // end remove

 87: template<class ItemType>
 88: void LinkedList<ItemType>::clear()
 89: {
 90:    while (!isEmpty())
 91:       remove(1);
 92: }  // end clear

 94: template<class ItemType>
 95: ItemType LinkedList<ItemType>::getEntry(int position) const throw(PrecondViolatedExcep)
 96: {
 97:    // Enforce precondition
 98:    bool ableToGet = (position >= 1) && (position <= itemCount);
 99:    if (ableToGet)
100:    {
101:       Node<ItemType>* nodePtr = getNodeAt(position);
102:       return nodePtr->getItem();
103:    }
104:    else
105:    {
106:       string message = "getEntry() called with an empty list or "; 
107:       message  = message + "invalid position.";
108:       throw(PrecondViolatedExcep(message)); 
109:    }  // end if
110: }  // end getEntry

112: template<class ItemType>
113: Node<ItemType>* LinkedList<ItemType>::getNodeAt(int position) const
114: {
115:    // Debugging check of precondition
116:    assert( (position >= 1) && (position <= itemCount) );
117:    
118:    // Count from the beginning of the chain
119:    Node<ItemType>* curPtr = headPtr;
120:    for (int skip = 1; skip < position; skip++)
121:       curPtr = curPtr->getNext();
122:       
123:    return curPtr;
124: }  // end getNodeAt

126: // RECURSIVE
127: template<class ItemType>
128: Node<ItemType>* LinkedList<ItemType>::insertNode(int position, Node<ItemType>* newNodePtr,
129:                                                  Node<ItemType>* subChainPtr)
130: {
131:    if (position == 1)
132:    {
133:       // Insert new node at beginning of subchain
134:       newNodePtr->setNext(subChainPtr);
135:       subChainPtr = newNodePtr;
136:       itemCount++;  // Increase count of entries
137:    }
138:    else
139:    {
140:       Node<ItemType>* afterPtr = insertNode(position - 1, newNodePtr, subChainPtr->getNext());
141:       subChainPtr->setNext(afterPtr);
142:    }  // end if
143:    
144:    return subChainPtr;
145: }  // end insertNode

147: //  End of implementation file.