Code Listings Chapter 18

 

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