数据结构与算法分析课后习题第五章

5.3 Write a program to compute the nubmer of collisions required in a long random sequence of insertions using linear probing, quadratic probing, and double hashing.

5.17 Implement a generic Map that supports the insert and lookup operations. The implementation will store a hash table of pairs (key, definition). You will lookup a definition by providing a key.

//5.3 dhashtable.hpp

#ifndef DHASHTABLE_HPP__
#define DHASHTABLE_HPP__

#include

template< typename HashItem >
class DoubleHashTable {
private:
 enum EntryType {EMPTY, ACTIVE, DELETED};

 class HashEntry {
 public:
  explicit HashEntry(HashItem i = HashItem(), EntryType t = EMPTY)
   : data(i), info(t)
  {}

 public:
  HashItem data;
  EntryType info;

 };

public:
 explicit DoubleHashTable(int size = 101 );

 bool contains(const HashItem& val) const;

 void makeEmpty();
 bool insert(const HashItem& val);
 bool remove(const HashItem& val);
 int collisions() const;

 
private:
 std::vector array_;
 int size_;
 int collisions_;

 bool isActive(int currentPos) const;
 int findPos(const HashItem& val);
 int myhash(const HashItem& val) const;
 int myhash2(const HashItem& val) const;

};

template< typename HashItem >
DoubleHashTable::DoubleHashTable(int size = 101)
: array_(size),collisions_(0)
{ makeEmpty(); }

template< typename HashItem >
bool DoubleHashTable::contains(const HashItem& val) const
{ return isActive(findPos(val)); }

template< typename HashItem >
void DoubleHashTable::makeEmpty()
{
 size_ = 0;
 for(int i = 0; i < array_.size(); ++i)
  array_[i].info = EMPTY;
}

template< typename HashItem >
bool DoubleHashTable::insert(const HashItem& val)
{
 int currentPos = findPos(val);
 if(isActive(currentPos))
  return false;

 array_[currentPos] = HashEntry(val, ACTIVE);

 return true;
}

template< typename HashItem >
bool DoubleHashTable::remove(const HashItem& val)
{
 int currentPos = findPos(val);
 if(!isActive(currentPos))
  return false;

 array[currentPos].info = DELETED;
 return true;
}

template< typename HashItem >
bool DoubleHashTable::isActive(int currentPos) const
{ return array_[currentPos].info == ACTIVE; }

template< typename HashItem >
int DoubleHashTable::findPos(const HashItem& val)
{
 int currentPos = myhash(val);

 while(array_[currentPos].info != EMPTY &&
  array_[currentPos].data != val)
 {
  currentPos += myhash2(val);
  ++collisions_;
  currentPos %= array_.size();
 }

 return currentPos;
}

template< typename HashItem >
int DoubleHashTable::myhash(const HashItem& val) const
{ return (val % array_.size()); }

template< typename HashItem >
int DoubleHashTable::myhash2(const HashItem& val) const
{ return (7 - (val % 7)); }

template< typename HashItem >
int DoubleHashTable::collisions() const
{ return collisions_; }

#endif

//lhashtable.hpp

#ifndef LHASHTABLE_HPP__
#define LHASHTABLE_HPP__

#include

template< typename HashItem >
class LinearHashTable {
private:
 enum EntryType {EMPTY, ACTIVE, DELETED};

 class HashEntry {
 public:
  HashEntry(HashItem i = HashItem(), EntryType t = EMPTY)
   : data(i), info(t)
  {}

 public:
  HashItem data;
  EntryType info;

 };

public:
 explicit LinearHashTable(int size = 101 );

 bool contains(const HashItem& val) const;

 void makeEmpty();
 bool insert(const HashItem& val);
 bool remove(const HashItem& val);
 int collisions() const;

 
private:
 std::vector array_;
 int size_;
 int collisions_;

 bool isActive(int currentPos) const;
 int findPos(const HashItem& val);
 int myhash(const HashItem& val) const;

};

template< typename HashItem >
LinearHashTable::LinearHashTable(int size = 101)
: array_(size),collisions_(0)
{ makeEmpty(); }

template< typename HashItem >
bool LinearHashTable::contains(const HashItem& val) const
{ return isActive(findPos(val)); }

template< typename HashItem >
void LinearHashTable::makeEmpty()
{
 size_ = 0;
 for(int i = 0; i < array_.size(); ++i)
  array_[i].info = EMPTY;
}

template< typename HashItem >
bool LinearHashTable::insert(const HashItem& val)
{
 int currentPos = findPos(val);
 if(isActive(currentPos))
  return false;

 array_[currentPos] = HashEntry(val, ACTIVE);

 return true;
}

template< typename HashItem >
bool LinearHashTable::remove(const HashItem& val)
{
 int currentPos = findPos(val);
 if(!isActive(currentPos))
  return false;

 array[currentPos].info = DELETED;
 return true;
}

template< typename HashItem >
bool LinearHashTable::isActive(int currentPos) const
{ return array_[currentPos].info == ACTIVE; }

template< typename HashItem >
int LinearHashTable::findPos(const HashItem& val)
{
 int offset = 1;
 int currentPos = myhash(val);

 while(array_[currentPos].info != EMPTY &&
  array_[currentPos].data != val)
 {
  currentPos += offset;
  ++offset;
  ++collisions_;
  currentPos %= array_.size();
 }

 return currentPos;
}

template< typename HashItem >
int LinearHashTable::myhash(const HashItem& val) const
{ return (val % array_.size()); }

template< typename HashItem >
int LinearHashTable::collisions() const
{ return collisions_; }

#endif

//qhashtable.hpp

#ifndef QHASHTABLE_HPP__
#define QHASHTABLE_HPP__

#include

template< typename HashItem >
class QuadraticHashTable {
private:
 enum EntryType {EMPTY, ACTIVE, DELETED};

 class HashEntry {
 public:
  explicit HashEntry(HashItem i = HashItem(), EntryType t = EMPTY)
   : data(i), info(t)
  {}

 public:
  HashItem data;
  EntryType info;

 };

public:
 explicit QuadraticHashTable(int size = 101 );

 bool contains(const HashItem& val) const;

 void makeEmpty();
 bool insert(const HashItem& val);
 bool remove(const HashItem& val);
 int collisions() const;

 
private:
 std::vector array_;
 int size_;
 int collisions_;

 bool isActive(int currentPos) const;
 int findPos(const HashItem& val);
 int myhash(const HashItem& val) const;

};

template< typename HashItem >
QuadraticHashTable::QuadraticHashTable(int size = 101)
: array_(size),collisions_(0)
{ makeEmpty(); }

template< typename HashItem >
bool QuadraticHashTable::contains(const HashItem& val) const
{ return isActive(findPos(val)); }

template< typename HashItem >
void QuadraticHashTable::makeEmpty()
{
 size_ = 0;
 for(int i = 0; i < array_.size(); ++i)
  array_[i].info = EMPTY;
}

template< typename HashItem >
bool QuadraticHashTable::insert(const HashItem& val)
{
 int currentPos = findPos(val);
 if(isActive(currentPos))
  return false;

 array_[currentPos] = HashEntry(val, ACTIVE);

 return true;
}

template< typename HashItem >
bool QuadraticHashTable::remove(const HashItem& val)
{
 int currentPos = findPos(val);
 if(!isActive(currentPos))
  return false;

 array[currentPos].info = DELETED;
 return true;
}

template< typename HashItem >
bool QuadraticHashTable::isActive(int currentPos) const
{ return array_[currentPos].info == ACTIVE; }

template< typename HashItem >
int QuadraticHashTable::findPos(const HashItem& val)
{
 int offset = 1;
 int currentPos = myhash(val);

 while(array_[currentPos].info != EMPTY &&
  array_[currentPos].data != val)
 {
  currentPos += offset * offset;
  ++offset;
  ++collisions_;
  currentPos %= array_.size();
 }

 return currentPos;
}

template< typename HashItem >
int QuadraticHashTable::myhash(const HashItem& val) const
{ return (val % array_.size()); }

template< typename HashItem >
int QuadraticHashTable::collisions() const
{ return collisions_; }

#endif

//5.17 hashtable.hpp

#ifndef HASHTABLE_HPP__
#define HASHTABLE_HPP__

#include
#include

template< typename HashObject, typename Object >
struct Pair {
 HashObject key;
 Object def;

 Pair(const HashObject& k = HashObject(),
  const Object& d = Object()) : key(k), def(d)
 {}

};

template< typename HashItem >
int hash(const HashItem& val, const size_t tableSize)
{ return val.key % tableSize; }

template<>
int hash(const Pair& str, const size_t tableSize)
{
 if(str.key.length() == 1)
  return str.key[0] % tableSize;
 else if(str.key.length() == 2)
  return (str.key[0] + 27 * str.key[1]) % tableSize;
 else
  return (str.key[0] + 27 * str.key[1] + 729 * str.key[2]) % tableSize;
}

template< typename HashItem >
class HashTable {
private:
 enum EntryType {EMPTY, ACTIVE, DELETED};

 class HashEntry {
 public:
  HashEntry(HashItem i = HashItem(), EntryType t = EMPTY)
   : data(i), info(t)
  {}

 public:
  HashItem data;
  EntryType info;

 };

public:
 explicit HashTable(int size = 101 );

 bool contains(const HashItem& val) const;

 void makeEmpty();
 bool insert(const HashItem& val);
 bool remove(const HashItem& val);
 bool isEmpty() const;

 bool isActive(int currentPos) const;
 int findPos(const HashItem& val);
 HashItem returnPos(int currentPos) const
 { return array_[currentPos].data; }
 
private:
 std::vector array_;
 int size_;

 int myhash(const HashItem& val) const;

};

template< typename HashItem >
HashTable::HashTable(int size = 101)
: array_(size)
{ makeEmpty(); }

template< typename HashItem >
bool HashTable::contains(const HashItem& val) const
{ return isActive(findPos(val)); }

template< typename HashItem >
void HashTable::makeEmpty()
{
 size_ = 0;
 for(int i = 0; i < array_.size(); ++i)
  array_[i].info = EMPTY;
}

template< typename HashItem >
bool HashTable::insert(const HashItem& val)
{
 int currentPos = findPos(val);
 if(isActive(currentPos))
  return false;

 array_[currentPos] = HashEntry(val, ACTIVE);
 ++size_;

 return true;
}

template< typename HashItem >
bool HashTable::remove(const HashItem& val)
{
 int currentPos = findPos(val);
 if(!isActive(currentPos))
  return false;

 array[currentPos].info = DELETED;
 --size_;
 return true;
}

template< typename HashItem >
bool HashTable::isActive(int currentPos) const
{ return array_[currentPos].info == ACTIVE; }

template< typename HashItem >
int HashTable::findPos(const HashItem& val)
{
 int offset = 1;
 int currentPos = myhash(val);

 while(array_[currentPos].info != EMPTY &&
  array_[currentPos].data.key != val.key)
 {
  currentPos += offset;
  ++offset;
  currentPos %= array_.size();
 }

 return currentPos;
}

template< typename HashItem >
int HashTable::myhash(const HashItem& val) const
{ return hash(val, array_.size()); }

template< typename HashItem >
bool HashTable::isEmpty() const
{ return size_ == 0; }

#endif

//hashmap.hpp

#ifndef HASHMAP_HPP__
#define HASHMAP_HPP__

#include "hashtable.hpp"

template< typename HashObject, typename Object >
class Dictionary
{
public:
 Dictionary()
 {}

 void insert(const HashObject& key, const Object& definition)
 { items.insert(Pair< HashObject, Object >(key, definition)); }
 
 const Object lookup(const HashObject& key)
 {
  int pos;
  if(items.isActive(pos = items.findPos(Pair(key))))
   return items.returnPos(pos).def;

  return Object();
 }
 
 bool isEmpty() const
 { return items.isEmpty(); }

 void makeEmpty()
 { items.makeEmpty(); }

private:
 HashTable< Pair< HashObject, Object > > items;

};

#endif 

你可能感兴趣的:(c++,数据结构)