/* 用链地址方法实现的HashTable,客户必须提供一个Hash函数 Hash函数必须具有以下特性: 1. 一个DataType类型的输入参数,传入被const reference 2. 返回一个0到size-1之间的整形,size是在HashTable中的 元素数 3. 函数名字被作为第一个参数传递到HashTable */ #include "Array.cpp" #include "LinkList.cpp" template <class DataType> class CHashTable { public: CHashTable(int (*hf)(const DataType &),int s); bool insert(const DataType & newObject); bool retrieve(DataType & retrieved); bool remove(DataType & removed); bool update(DataType & updateObject); void makeEmpty(); private: Array<CLinkList<DataType> > table; int (*hashfunc)(const DataType &); }; #include "HashTable.h" template <class DataType> CHashTable<DataType>::CHashTable(int (*hf)(const DataType &),int s) : table(s) { hashfunc=hf; } template <class DataType> bool CHashTable<DataType>::insert(const DataType & newObject) { int location=hashfunc(newObject); if (location<0 || location>=table.length()) { return false; } table[location].insert(newObject); return true; } template <class DataType> bool CHashTable<DataType>::retrieve(DataType & retrieved) { int location=hashfunc(retrieved); if (location<0 || location>=table.length()) { return false; } if (!table[location].retrieve(retrieved)) { return false; } return true; } template <class DataType> bool CHashTable<DataType>::update(DataType & updateObject) { int location=hashfunc(updateObject); if (location<0 || location>=table.length()) { return false; } if (!table[location].find(updateObject)) { return false; } table[location].replace(updateObject); return true; } template <class DataType> void CHashTable<DataType>::makeEmpty() { for (int i=0;i<table.length();i++) { table[i].makeEmpty(); } } #include <iostream> #include <string> #include "HashTable.cpp" using namespace std; struct MyStruct { string str; int num; bool operator==(const MyStruct & r) { return str==r.str; } }; const int SIZE1=97,SIZE2=199; int hash1(const MyStruct & obj); int hash2(const MyStruct & obj); void main() { CHashTable<MyStruct> ht1(hash1,SIZE1),ht2(hash2,SIZE2); MyStruct myjob; myjob.str="elephant"; myjob.num=25; ht1.insert(myjob); myjob.str="giraffe"; myjob.num=50; ht1.insert(myjob); myjob.str="element"; myjob.num=80; ht2.insert(myjob); MyStruct myjob2; myjob2.str="element"; ht2.retrieve(myjob2); cout<<"myjob2.num:"<<myjob2.num<<endl; myjob2.str="elephant"; ht1.retrieve(myjob2); cout<<"myjob2.num:"<<myjob2.num<<endl; } int hash1(const MyStruct & obj) { int sum=0; for (int i=0;i<3 && i<int(obj.str.length());i++) { sum+=obj.str[i]; } return sum % SIZE1; } int hash2(const MyStruct & obj) { int sum=0; for (int i=int(obj.str.length())-1;i>-1 && i>int(obj.str.length())-7;i--) { sum+=obj.str[i]; } return sum % SIZE2; }