|
-
June 24th, 2004, 12:28 AM
#1
hashing help
Hi. I am supposed to store a Student class in a hash table. The hash table is supposed to use the student number as the key. My professor already created the hash table code, and I am supposed to use it to create a main program to store student numbers in it. I am even having a problem creating a hash table object, which my prof refers to as an index.
Here is my professor's code for index.hpp
Code:
#ifndef INDEXCHT_HPP
#define INDEXCHT_HPP
// Index: Header File
template <class Etype, class Ktype>
// Index stores elements of Etype with keys of Ktype
// Assumptions: 1) Key values are unique
// 2) Etype is an object with methods Key and Hash
class Index
{
public:
enum KindOfEntry { active, empty, deleted };
// Constructor
//
// Input : None
// Purpose: To create an empty Index
// Output : None
Index ( );
// Copy constructor
//
// Input : None
// Purpose: To initialize Index to I
// Output : None
Index ( const Index & I );
// Destructor
//
// Input : None
// Purpose: To free memory of Index
// Output : None
~Index ( );
// Copy assignment
//
// Input : Index I
// Purpose: To assign I to current Index
// Output : Current Index
const Index & operator= ( const Index & I );
// Insert
//
// Input : Element E
// Purpose: To place E into the Index
// Assume : No duplicate keys are allowed
// Output : 1 if successful; 0 otherwise
int Insert ( const Etype & E );
// Update
//
// Input : Element E
// Purpose: To replace E in the Index
// Output : 1 if successful; 0 otherwise
int Update ( const Etype & E );
// Remove
//
// Input : Key K
// Purpose: To remove the element with key K from Index
// Output : 1 if successful; 0 otherwise
int Remove ( const Ktype & K );
// Retrieve
//
// Input : Key K
// Purpose: To return element E with key K from Index
// Output : Element E and 1 if successful; 0 otherwise
int Retrieve ( const Ktype & K, Etype & E ) const;
// Clear
//
// Input : None
// Purpose: To re-initialize Index to empty
// Output : None
void Clear ( );
private:
// DoubleArray
//
// Input : None
// Purpose: To double the maximum size of Index (to the nearest prime)
// Output : None
void DoubleArray ( );
// Prime
//
// Input : Integer N
// Purpose: To check if N is a prime number
// Output : 1 if N is prime; 0 otherwise
int Prime ( int N );
// NextPrime
//
// Input : Integer N
// Purpose: To find the next prime integer greater than N
// Output : The next prime integer greater than N
int NextPrime ( int N );
// FindPos
//
// Input : Key K
// Purpose: To find the location of the first empty hash entry or
// To find the location of the element with key K
// (whichever comes first)
// Output : The location
unsigned int FindPos ( const Ktype & K ) const;
// Data members
// Hash table entry
struct HashEntry
{
Etype Element;
KindOfEntry Info;
// HashEntry constructors
HashEntry ( ) : Info ( empty )
{ }
HashEntry ( const Etype & E, KindOfEntry T = active ) :
Element ( E ), Info ( T )
{ }
};
// Current and maximum size of Index
int CurrentSize, MaxSize;
// Dynamic array to store the elements of Index
HashEntry *Array;
};
#endif
And here is the index.cpp
Code:
#include "indexcht.hpp"
#include <iostream.h>
// Index: Implementation File ( Closed Hash Table )
// Notes: 1) Delete and new functions are assumed to take constant time.
//
// 2) Expected time complexity is based on linear probing
// (NOT quadratic probing as implemented).
//
// 3) Non-independence of probes (i.e. primary clustering)
// is assumed.
//
// 4) U is defined as the percentage of empty cells.
// L (Load factor) is defined as the percentage of non-empty cells.
//
// 5) The hash function is assumed to take constant time.
// Initial size of Index
static const int InitHTSize = 11; // Prime
// DoubleArray
//
// Time complexity: O(n)
template <class Etype, class Ktype>
void
Index<Etype,Ktype>::DoubleArray ( )
{
HashEntry *OldArray = Array;
int OldSize = MaxSize;
CurrentSize = 0;
MaxSize = NextPrime ( 2*MaxSize ); // Table size must be prime
Array = new HashEntry [MaxSize];
for ( int i=0; i<OldSize; i++ )
if ( OldArray[i].Info == active )
Insert ( OldArray[i].Element );
delete [] OldArray;
}
// Prime
//
// Time complexity: O(sqrt(n))
template <class Etype, class Ktype>
int
Index<Etype,Ktype>::Prime ( int N )
{
for ( int i=3; i*i <= N; i+=2 )
if ( N % i == 0 )
return 0;
return 1;
}
// NextPrime
//
// Expected time complexity: O(log n)
template <class Etype, class Ktype>
int
Index<Etype,Ktype>::NextPrime ( int N )
{
// Ensure N is odd
//if ( N % 2 == 0 )
N++;
//else
// N += 2;
for (; !Prime ( N ); N += 2 );
return N;
}
// FindPos
//
// Expected time complexity (with linear probing):
//
// (1 + (1/(U^2)))/2 if Element with K is NOT found
// (1 + (1/U))/2 if Element with K is found
template <class Etype, class Ktype>
unsigned int
Index<Etype,Ktype>::FindPos ( const Ktype & Key ) const
{
Etype E;
unsigned int i = 0;
unsigned int CurrentPos = E.Hash ( Key ) % MaxSize;
while ( Array[CurrentPos].Info != empty &&
Array[CurrentPos].Element.Key( ) != Key )
{
// Quadratic probing
CurrentPos += (2 * ++i) - 1; // Step size is the next odd number
if ( CurrentPos >= MaxSize ) // Wrap around
CurrentPos -= MaxSize;
}
return CurrentPos;
}
// Constructor
//
// Time complexity: O(1)
template <class Etype, class Ktype>
Index<Etype,Ktype>::Index ( ) : MaxSize ( InitHTSize ), CurrentSize ( 0 )
{
Array = new HashEntry [MaxSize];
}
// Copy constructor
//
// Time complexity: O(n)
template <class Etype, class Ktype>
Index<Etype,Ktype>::Index ( const Index<Etype,Ktype> & Rhs )
{
Array = NULL;
*this = Rhs;
}
// Destructor
//
// Time complexity: O(1)
template <class Etype, class Ktype>
Index<Etype,Ktype>::~Index ( )
{
delete [] Array;
}
// Copy assignment
//
// Time complexity: O(n)
template <class Etype, class Ktype>
const Index<Etype,Ktype> &
Index<Etype,Ktype>::operator= ( const Index<Etype,Ktype> & Rhs )
{
if ( this != &Rhs )
{
delete [] Array;
MaxSize = Rhs.MaxSize;
CurrentSize = Rhs.CurrentSize;
Array = new HashEntry [MaxSize];
for ( int i=0; i<MaxSize; i++ )
Array[i] = Rhs.Array[i];
}
return *this;
}
// Insert
//
// Amortized expected time complexity:
//
// (1 + (1/(U^2)))/2 if 1 is returned
// (1 + (1/U))/2 if 0 is returned
template <class Etype, class Ktype>
int
Index<Etype,Ktype>::Insert ( const Etype & Element )
{
unsigned int CurrentPos = FindPos ( Element.Key ( ) );
if ( Array[CurrentPos].Info == active )
return 0;
else
{
if ( Array[CurrentPos].Element != Element )
{
Array[CurrentPos] = HashEntry ( Element );
// U >= 0.5 (Table size must be at least half empty)
if ( ++CurrentSize > MaxSize/2 )
DoubleArray ( );
}
else
Array[CurrentPos].Info = active;
return 1;
}
}
// Update
//
// Expected time complexity:
//
// (1 + (1/(U^2)))/2 if 0 is returned
// (1 + (1/U))/2 if 1 is returned
template <class Etype, class Ktype>
int
Index<Etype,Ktype>::Update ( const Etype & Element )
{
unsigned int CurrentPos = FindPos ( Element.Key ( ) );
if ( Array[CurrentPos].Info == active )
{
Array[CurrentPos] = HashEntry ( Element );
return 1;
}
else
return 0;
}
// Remove
//
// Expected time complexity:
//
// (1 + (1/(U^2)))/2 if 0 is returned
// (1 + (1/U))/2 if 1 is returned
template <class Etype, class Ktype>
int
Index<Etype,Ktype>::Remove ( const Ktype & Key )
{
unsigned int CurrentPos = FindPos ( Key );
if ( Array[CurrentPos].Info == active )
{
Array[CurrentPos].Info = deleted;
return 1;
// Note that CurrentSize remains unchanged
}
else
return 0;
}
// Retrieve
//
// Expected time complexity:
//
// (1 + (1/(U^2)))/2 if 0 is returned
// (1 + (1/U))/2 if 1 is returned
template <class Etype, class Ktype>
int
Index<Etype,Ktype>::Retrieve ( const Ktype & Key, Etype & Element ) const
{
unsigned int CurrentPos = FindPos ( Key );
if ( Array[CurrentPos].Info == active )
{
Element = Array[CurrentPos].Element;
return 1;
}
else
return 0;
}
// Clear
//
// Time complexity: O(n)
template <class Etype, class Ktype>
void
Index<Etype,Ktype>::Clear ( )
{
CurrentSize = 0;
for ( int i=0; i<MaxSize; i++ )
Array[i].Info = empty;
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|