Code:
#ifndef _hashTable_h
#define _hashTable_h
#include <iostream>
#include <string>
using namespace std;
template<class KeyType, class DataType>
struct mypair
{ KeyType key;
DataType data;
};
template<class KeyType, class DataType>
class hashTable
{
public:
//hashTable();
//Default constructor. In final version delete this constructor
//and only have the next constructor. You can't have both since
//the second one has a default parameter and thus can be used
//with no argument and becomes the default constructor.
hashTable(long int tSize = 0);
//Constructor function. Dynamically allocates the arrays, table
//and status, with dimensions of the next prime number > tSize.
//Initializes the status array to show all positions in the table
//are empty and initializes size, tableSize, numSearches and
//numProbes. Uses non-member function nextPrime.
~hashTable();
//Destuctor. Deletes dynamically allocated arrays table and status.
//Commented out so program runs before this is written.
void find(const KeyType& k, long int& i, bool& found);
//Looks for key, k, in table. If found then sets i to the subscript
//where the key is located and sets found to true. If not found
//then sets i to the subscript where the key could be inserted
//and sets found to false. Uses linear probing for collision
//resolution with inc determined from the hash value as follows:
//i = hash(...); inc = i; if (inc == 0) inc = tableSize - 1 ; This
//is a little better than always taking inc = 1. Uses non-member
//function hash.
void insert(const KeyType& k, const DataType& d);
//Inserts a pair with key k and data d into the table. If a pair
//with the same key part already occurs in the table then it prints
//an error message and does not insert the pair. If the table is
//now more than 75% full then it rehashes into a larger table. Uses
//the public member function find and the private member function
//rehash.
//************************************************************************
//The following functions provide simialr capabilties to iterators in STL.
//They allow one to examine all elements of the hash table. You could use
//these for example to output all elements of the hash table or to copy all
//elements to a vector outside the hashTable class for sorting, etc.
const mypair<KeyType, DataType>& element(long int i) const;
//Returns the pair at subscript i in the table. Cannot be used
//to assign a new value to the pair.
DataType& data(long int i) const;
//Returns a reference to the data at subscript i in the table.
//Can be used to assign a new value to the data.
long int begin() const;
//Returns the subscript of the first element in the table; returns
//the same value as end(), i.e. tableSize, if the table is empty.
long int end() const;
//Returns subscript just past end of table, i.e. tableSize.
long int next(long int i) const;
//Returns the subscript of the next element after i; if there is no
//next element then returns the same as end(), i.e. tableSize.
bool operator < (const mypair<KeyType, DataType>& q);
//*************************************************************************
float averageSearchLength() const;
//returns the average length of all searches numProbes/numSearches.
//void setDemo();
//delete this function prototype in final version
//Sets up a hashTable to demonstrate the functions begin(), end(),
//next(i), element(i), data(i) without having all the other functions
//like the constructor and insert functions already written.
private:
mypair<KeyType, DataType>* table; //dynamically allocated array of pairs
short int* status; //dynamically allocated status array; contains
//staus info: 0=empty, 1=occupied
long int size; //number of elements in table
long int tableSize; //size of table array
long int numSearches; //total number of searches done in looking up keys.
//Increment numSearches each time find called.
long int numProbes; //total number of probes done during all searches.
//Increment each time find looks at a spot.
void rehash();
//The rehash function remembers the current table, status and tableSize
//by assigning them to local variables, oldTable, oldStatus and
//oldTableSize. It then dynamically allocates new table and status
//arrays of size the next larger prime than oldTableSize and sets
//tableSize to the new size. It then goes through the old table
//and rehashes each element into the new table using the insert
//function. Uses non-member function nextPrime.
};
template<class KeyType, class DataType>
const mypair<KeyType, DataType>&
hashTable<KeyType, DataType>::element(long int i) const
{ return table[i];
}
template<class KeyType, class DataType>
DataType& hashTable<KeyType, DataType>::data(long int i) const
{ return table[i].data;
}
template<class KeyType, class DataType>
long int hashTable<KeyType, DataType>::begin() const
{ long int i = 0;
while(i < tableSize && status[i] != 1)
i++;
return i;
}
template<class KeyType, class DataType>
long int hashTable<KeyType, DataType>::end() const
{ return tableSize;
}
template<class KeyType, class DataType>
long int hashTable<KeyType, DataType>::next(long int i) const
{
i++;
while(i < tableSize && status[i] != 1)
i++;
return i;
}
template<class KeyType, class DataType>
float hashTable<KeyType, DataType>::averageSearchLength()const
{
return float(numProbes/numSearches);
}
/*template<class KeyType, class DataType>
hashTable<KeyType, DataType>::hashTable()
{
tableSize=nextPrime(0);
table = new mypair<KeyType, DataType>[tableSize];
status = new short int [tableSize];
for(int k=0;k < tableSize; k++)status[k]=0;//indicates all spaces are empty
size=0;
numSearches=0;
numProbes=0;
}*/
template<class KeyType, class DataType>
hashTable<KeyType, DataType>::hashTable(long int tSize=0)
{
tableSize=nextPrime(tSize);
table = new mypair<KeyType, DataType>[tableSize];
status=new short int [tableSize];
for(int k=0;k<tableSize;k++)status[k]=0;
size=0;
numSeaches=0;
numProbes=0;
}
template<class KeyType, class DataType>
hashTable<KeyType, DataType>::~hashTable()
{
delete [] table;
delete [] status;
}
//delete the function setDemo in final version
/*template<class KeyType, class DataType>
void hashTable<KeyType, DataType>::setDemo()
{ long int i;
cout<<"IN DEMO"<<endl;
tableSize = nextPrime(20);
cout<<"tableSize = "<<tableSize<<endl;
table = new mypair<KeyType, DataType>[tableSize];
status = new short int[tableSize];
for(i = 0; i < tableSize; i++)
status[i] = 0;
i = hash("ABCD", tableSize);
status[i] = 1;
table[i].key = "ABCD";
table[i].data = 5;
cout<<"ABCD 5 at subscript "<<i<<endl;
i = hash("WXYZ", tableSize);
status[i] = 1;
table[i].key = "WXYZ";
table[i].data = 7;
cout<<"WXYZ 7 at subscript "<<i<<endl<<endl;
size = 2;
cout<<endl;
}*/
template<class KeyType, class DataType>
bool operator < (const mypair<KeyType, DataType>& q)
{
if(p.data < q.data)return true;
else if ( p.data > q.data)return false;
else
return (p.key < q.key);
}
//************************************************************************
//Non-member functions used in hashTable class.
//This is the hash function to use for strings. If the KeyType is
//anything other than string then this non-member function would
//need to be changed to hash that type of key.
long int hash(string s, int tableSize)
{ int j;
unsigned long int sum = 0;
for (j = 0; j < s.length(); j++)
sum = (sum << 5) + s[j];
return sum % tableSize;
}
//Returns the next prime >= n from a list of primes where
//each is about twice as big as the previous one.
long int nextPrime(long int n)
{ long int i;
long int p[18] = { 31, 61, 127, 251, 509, 1021,
2039, 4093, 8191, 16381, 32749, 65521,
131071, 262139, 524287, 1048573, 2097143, 4194301
};
for (i = 0; i < 18; i++)
if (p[i] > n) return p[i];
cerr<<"Next prime too large"<<endl;
return p[17];
}
//************************************************************************
#endif
the main code (incomplete)