Listing 18-1 An interface for the ADT dictionary |
/** An interface for the ADT dictionary. @file DictionaryInterface.h */ #ifndef _DICTIONARY_INTERFACE #define _DICTIONARY_INTERFACE #include "NotFoundException.h" template < class KeyType, class ItemType > class DictionaryInterface { public: /** Sees whether this dictionary is empty. @return True if the dictionary is empty; otherwise returns false. */ virtual bool isEmpty ()const = 0; /** Gets the number of items in this dictionary. @return The number of items in the dictionary. */ virtual int getNumberOfItems () const = 0; /** Inserts an item into this dictionary according to the items search key. @pre The search key of the new item differs from all search keys presently in the dictionary. @post If the insertion is successful, newItem is in its proper position within the dictionary. @param searchKey The search key associated with the item to be inserted. @param newItem The item to add to the dictionary. @return True if item was successfully added, or false if not. */ virtual bool add (const KeyType & searchKey, const ItemType & newItem) = 0; /** Removes an item with the given search key from this dictionary. @post If the item whose search key equals searchKey existed in the dictionary, the item was removed. @param searchKey The search key of the item to be removed. @return True if the item was successfully removed, or false if not. */ virtual bool remove (const KeyType & searchKey) = 0; /** Removes all entries from this dictionary. */ virtual void clear () = 0; /** Retrieves an item with a given search key from a dictionary. @post If the retrieval is successful, the item is returned. @param searchKey The search key of the item to be retrieved. @return The item associated with the search key. @throw NotFoundException if the item does not exist. */ virtual ItemType getItem (const KeyType & searchKey) const throw (NotFoundException) = 0; /** Sees whether this dictionary contains an item with a given search key. @post The dictionary is unchanged. @param searchKey The search key of the item to be retrieved. @return True if an item with the given search key exists in the dictionary. */ virtual bool contains (const KeyType & searchKey) const = 0; /** Traverses this dictionary and calls a given client function once for each item. @post The given functions action occurs once for each item in the dictionary and possibly alters the item. @param visit A client function. */ virtual void traverse (void visit (ItemType &)) const = 0; }; // end DictionaryInterface #endif |
Listing 18-2 A header file for a class of dictionary entries |
/** A class of entry objects for an array-based implementation of the ADT dictionary. @file Entry.h */ #ifndef _ENTRY #define _ENTRY template < class KeyType, class ItemType > class Entry { private: ItemType item; KeyType searchKey; protected: void setKey (const KeyType & searchKey); public: Entry (); Entry (ItemType newEntry, KeyType searchKey); ItemType getItem () const; KeyType getKey () const; void setItem (const ItemType & newEntry); bool operator== (const Entry < KeyType, ItemType > &rightHandItem) const; bool operator> (const Entry < KeyType, ItemType > &rightHandItem) const; }; // end Entry #include "Entry.cpp" #endif |
Listing 18-3 A header file for the class ArrayDictionary |
/** An array-based implementation of the ADT dictionary that organizes its data items in sorted search-key order. Search keys in the dictionary are unique. @file ArrayDictionary.h */ #ifndef _ARRAY_DICTIONARY #define _ARRAY_DICTIONARY #include "DictionaryInterface.h" #include "Entry.h" #include "NotFoundException.h" template < class KeyType, class ItemType > class ArrayDictionary:public DictionaryInterface < KeyType, ItemType > { private: static const int DEFAULT_CAPACITY = 21; // Small capacity to test for // a full dictionary Entry < KeyType, ItemType > *items; // Array of dictionary entries int itemCount; // Current count of dictionary items int maxItems; // Maximum capacity of the dictionary void destroyDictionary (); int findEntryIndex (int firstIndex, int lastIndex, const KeyType & searchKey) const; public: ArrayDictionary (); ArrayDictionary (int maxNumberOfEntries); ArrayDictionary (const ArrayDictionary < KeyType, ItemType > &dict); virtual ~ ArrayDictionary (); bool isEmpty () const; int getNumberOfItems () const; bool add (const KeyType & searchKey, const ItemType & newItem); bool remove (const KeyType & searchKey); void clear (); ItemType getItem (const KeyType & searchKey) const throw (NotFoundException); bool contains (const KeyType & searchKey) const; /** Traverses the items in this dictionary in sorted search-key order and calls a given client function once for each item. */ void traverse (void visit (ItemType &)) const; }; // end ArrayDictionary #include "ArrayDictionary.cpp" #endif |
Listing 18-A,
Public method add
|
template < class KeyType, class ItemType > bool ArrayDictionary < KeyType, ItemType >::add (const ItemType & newItem, const KeyType & searchKey) { bool ableToInsert = (itemCount < maxItems); if (ableToInsert) { // Make room for new entry by shifting all entries at // positions >= newPosition toward the end of the array // (no shift if newPosition == itemCount + 1). Performing // a binary search doesnt help here, because we need to // shift the entries while looking for the insertion location. int index = itemCount; // Short-circuit evaluation is important while ((index > 0) && (searchKey < items[index - 1].getKey ())) { items[index] = items[index - 1]; index -; } // end while // Insert new entry items[index] = Entry < KeyType, ItemType > (newItem, searchKey); itemCount++; // Increase count of entries } // end if return ableToInsert; } // end add |
Listing 18-4 A header file for the class TreeDictionary |
/** A binary search tree implementation of the ADT dictionary that organizes its data items in sorted search-key order. Search keys in the dictionary are unique. @file TreeDictionary.h */ #ifndef _TREE_DICTIONARY #define _TREE_DICTIONARY #include "DictionaryInterface.h" #include "BinarySearchTree.h" #include "Entry.h" #include "NotFoundException.h" template < class KeyType, class ItemType > class TreeDictionary:public DictionaryInterface < KeyType, ItemType > { private: // Binary search tree of dictionary entries BinarySearchTree < Entry < KeyType, ItemType > >itemTree; void traversalHelper (Entry < KeyType, ItemType > &theEntry); public: TreeDictionary (); TreeDictionary (int maxNumberOfEntries); TreeDictionary (const TreeDictionary < KeyType, ItemType > &dict); virtual ~ TreeDictionary (); ArrayDictionary (); ArrayDictionary (int maxNumberOfEntries); ArrayDictionary (const ArrayDictionary < KeyType, ItemType > &dict); virtual ~ ArrayDictionary (); bool isEmpty () const; int getNumberOfItems () const; bool add (const KeyType & searchKey, const ItemType & newItem); bool remove (const KeyType & searchKey); void clear (); ItemType getItem (const KeyType & searchKey) const throw (NotFoundException); bool contains (const KeyType & searchKey) const; /** Traverses the items in this dictionary in sorted search-key order and calls a given client function once for each item. */ void traverse (void visit (ItemType &)) const;
}; // end TreeDictionary
#include "TreeDictionary.cpp"
#endif
|
Listing 18-5 The class HashedEntry |
/** A class of entry objects for a hashing implementation of the
ADT dictionary.
@file HashedEntry.h */
#ifndef _HASHED_ENTRY
#define _HASHED_ENTRY
#include "Entry.h"
template < class KeyType, class ItemType > class HashedEntry:public Entry < KeyType, ItemType >
{
private:
HashedEntry < KeyType, ItemType > *nextPtr;
public:
HashedEntry ();
HashedEntry (ItemType newEntry, KeyType searchKey);
HashedEntry (ItemType newEntry, KeyType searchKey, HashedEntry < KeyType, ItemType > *nextEntryPtr);
void setNext (HashedEntry < KeyType, ItemType > *nextEntryPtr);
HashedEntry < KeyType, ItemType > *getNext ()const;
}; // end HashedEntry
#include "HashedEntry.cpp"
#endif
|
Listing 18-B Definitions of add and remove functions. |
template < class KeyType, class ItemType > bool HashedDictionary < KeyType, ItemType >::add (const ItemType & newItem,
const KeyType & searchKey)
{
// Create entry to add to dictionary
HashedEntry < KeyType, ItemType > *entryToAddPtr = new HashedEntry < KeyType, ItemType > (newItem, searchKey);
// Compute the hashed index into the array
int itemHashIndex = getHashIndex (searchKey);
// Add the entry to the chain at itemHashIndex
if (hashTable[itemHashIndex] == nullptr)
{
hashTable[itemHashIndex] = entryToAddPtr;
}
else
{
entryToAddPtr->setNext (hashTable[itemHashIndex]);
hashTable[itemHashIndex] = entryToAddPtr;
} // end if
return true;
} // end add
template < class KeyType, class ItemType > bool HashedDictionary < KeyType, ItemType >::remove (const KeyType & searchKey)
{
bool itemFound = false;
// Compute the hashed index into the array
int itemHashIndex = getHashIndex (searchKey);
if (hashTable[itemHashIndex] != nullptr)
{
// Special case - first node has target
if (searchKey == hashTable[itemHashIndex]->getKey ())
{
HashedEntry < KeyType, ItemType > *entryToRemovePtr = hashTable[itemHashIndex];
hashTable[itemHashIndex] = hashTable[itemHashIndex]->getNext ();
delete entryToRemovePtr;
entryToRemovePtr = nullptr; // For safety
itemFound = true;
}
else // Search the rest of the chain
{
HashedEntry < KeyType, ItemType > *prevPtr = hashTable[itemHashIndex];
HashedEntry < KeyType, ItemType > *curPtr = prevPtr->getNext ();
while ((curPtr != nullptr) && !itemFound)
{
// Found item in chain so remove that node
if (searchKey == curPtr->getKey ())
{
prevPtr->setNext (curPtr->getNext ());
delete curPtr;
curPtr = nullptr; // For safety
itemFound = true;
}
else // Look at next entry in chain
{
prevPtr = curPtr;
curPtr = curPtr->getNext ();
} // end if
} // end while
} // end if
} // end if
return itemFound;
} // end remove
|