Please send questions to
st10@humboldt.edu .
/************************************************************/
/* implementation of .h file adapted from */
/* http://www.cs.colorado.edu/~main/chapter12/table2.h */
/* */
/* Main and Savitch, "Data Structures and Other Objects */
/* using C++", 2nd edition, Addison-Wesley, Ch.12, p.587 */
/************************************************************/
//-----------------------------------------------------------
// File: hashtable.template
// Name: Sharon Tuttle and (your name here)
// (implementing an adaptation of a .h file adapted from
// Savitch and Main)
// last modified: 4-20-05
//
// Template Class: hashtable<RecordType> (a hash table
// of records of type RecordType)
//
// Because this is a template class, it is included in
// the header file, and not compiled separately.
//**************************************************************
#include "hashtable.h"
#include <iostream>
using namespace std;
/**********************************************************/
/* CONSTRUCTORS and DESTRUCTOR */
/**********************************************************/
// constructor
//
// postcondition: creates an empty hashtable instance
// of table_size given_table_size.
//
template <typename RecordType>
hashtable<RecordType>::hashtable( size_t given_table_size )
{
table_size = given_table_size;
data = new node<RecordType>*[table_size];
total_records = 0;
// initialize each bucket so that it initially is NULL
YOU FILL IN
}
// copy constructor
//
template <typename RecordType>
hashtable<RecordType>::hashtable(const hashtable<RecordType>& source)
{
total_records = source.total_records;
node<RecordType> *tail_ptr; // needed for argument of list_copy
// use node's list toolkit list_copy to copy over
// each bucket's chain
for (int i=0; i<table_size; i++)
{
list_copy(source.data[i], data[i], tail_ptr);
tail_ptr = NULL;
}
}
// destructor
//
template <typename RecordType>
hashtable<RecordType>::~hashtable( )
{
// call node's list_clear toolkit function for each bucket
YOU FILL IN
}
/*******************************************************/
/* ACCESSORS and other constant member functions */
/* (observers) */
/*******************************************************/
// find
//
// postconditions: if a record is in the hashtable with
// the specified key this_key, then found is set to
// true and result is set to a copy of the record
// with that key. Otherwise found is false and the
// result contains garbage.
//
template <typename RecordType>
void hashtable<RecordType>::find(int this_key, bool& found,
RecordType& result) const
{
size_t index;
// where should record with this_key be?
YOU FILL IN
node<RecordType> *curr;
curr = data[index];
YOU FILL IN THE REST
}
// is_present
//
// postcondition: returns true if there is a record
// in the hashtable with key of this_key. Othewise,
// returns false.
//
template <typename RecordType>
bool hashtable<RecordType>::is_present(int this_key) const
{
size_t index;
// where should this_key's record be?
YOU FILL IN
node<RecordType> *curr;
YOU FILL IN THE REST
}
// size
//
// postcondition: returns the total number of records
// in the hashtable.
//
template <typename RecordType>
size_t hashtable<RecordType>::get_size( ) const
{
return total_records;
}
// print_hashtable
//
// postcondition: prints the keys within non-empty
// buckets, 1 non-empty bucket per line
//
template <typename RecordType>
void hashtable<RecordType>::print_hashtable( ) const
{
node<RecordType> *curr;
cout << "printing non-empty buckets of hash table: " << endl;
cout << "-----------------------------------------" << endl;
for (int i=0; i<table_size; i++)
{
if (data[i] != NULL)
{
cout << "bucket[" << i << "]: ";
curr = data[i];
// while haven't reached end of chain, print
// key of current record in chain
YOU FILL IN
cout << endl;
}
}
cout << endl;
}
/****************************************************/
/* MODIFIERS and other modifying member functions */
/****************************************************/
// insert
//
// preconditions: entry.get_key( ) >= 0. Also, if
// entry.get_key( ) is not already a key in the
// hashtable, then the hashtable has space for another
// record (haven't exceeded free store...)
// postconditions: if the table already had a record
// with key equal to entry.get_key( ), then that record
// is replaced by entry. Otherwise, entry has been
// added as a new record of the hashtable.
//
template <typename RecordType>
void hashtable<RecordType>::insert(const RecordType& entry)
{
size_t index;
// find out where this entry should go
YOU FILL IN
// IF this key is NOT already in the hashtable --- where
// should it go? Put it there.
YOU FILL IN
// ELSE replace key's current entry with this new entry
else
{
node<RecordType> *curr;
// we KNOW key is HERE, or we wouldn't have reached here!
// (else clause for !is_present(key) )
YOU FILL IN THE REST
}
}
// remove
//
// postconditions: if a record was in the hashtable with
// the specified key this_key, then that record has
// been removed; otherwise the hashtable is unchanged.
//
template <typename RecordType>
void hashtable<RecordType>::remove(int this_key)
{
size_t index;
// where should this_key's entry be?
YOU FILL IN
node<RecordType> *curr;
node<RecordType> *prev = NULL;
// point to chain where element would be...
YOU FILL IN
// if element is head of a non-null chain...
YOU FILL IN
// else...
YOU FILL IN
}
/********************************************************/
/* overloaded operators */
/********************************************************/
// =
//
// postcondition: the hashtable that activated this
// will be made to have the same records as source
//
template <typename RecordType>
void hashtable<RecordType>::operator =(
const hashtable<RecordType>& source)
{
node<RecordType> *tail_ptr;
if (this == &source)
{
return;
}
for (int i=0; i<table_size; i++)
{
list_clear(data[i]);
list_copy(source.data[i], data[i], tail_ptr);
tail_ptr = NULL;
}
total_records = source.total_records;
}
/****************************************************/
/* PRIVATE HELPER MEMBER FUNCTIONS */
/****************************************************/
// hash
//
// postconditions: returns a number in the range
// [0, table_size) based on key this_key.
//
template <typename RecordType>
size_t hashtable<RecordType>::hash(int this_key) const
{
return this_key % table_size;
}