1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <string> 5 6 using namespace std; 7 8 bool isprime(int n) { 9 int lim = sqrt(n) + 1; 10 for (int i = 2;i <= lim;i++)if (n%i == 0)return 0; 11 return 1; 12 } 13 14 int nextprime(int n) { 15 for (int i = n + 1;;i++)if (isprime(i))return i; 16 } 17 18 enum State 19 { 20 EMPTY, 21 EXIST, 22 DELETE, 23 }; 24 25 struct Node { 26 string key; 27 State s; 28 Node(const string& key = "", State s = EMPTY) :key(key), s(s) {} 29 Node& operator=(const Node&rhs) { 30 key = rhs.key; 31 s = rhs.s; 32 return *this; 33 } 34 }; 35 36 int myhash(const string& key) { 37 int hashVal = 0; 38 for (size_t i = 0;i < key.length();i++)hashVal += 37 * hashVal + key[i]; 39 40 return hashVal; 41 } 42 43 class hashTable { 44 typedef Node obj; 45 friend void print(const hashTable& h) { 46 for (int i = 0;i < h.size();i++) 47 if (h._table[i].s == EXIST)cout << h._table[i].s << endl; 48 } 49 private: 50 vector<obj> _table; 51 int num; 52 int findEle(const string&); 53 size_t size()const { return _table.size(); }//不加const限定符常引用对象无法调用此函数 54 void chk_memory(); 55 public: 56 hashTable():num(0) {}; 57 bool find(const obj&); 58 bool insert(const obj&); 59 bool remove(const obj&); 60 }; 61 62 inline 63 int hashTable::findEle(const string& key) {//查找是否存在 64 if (num == 0 || size() == 0)return -1; 65 int hv = myhash(key) % size(); 66 67 while (hv >= 0 && _table[hv].s != EMPTY) {//必须保证表不为空,不然可能死循环 68 State cur = _table[hv].s; 69 if (cur == DELETE || _table[hv].key != key) { 70 hv++;//线性探测法 71 if (hv == size())hv = 0; 72 continue; 73 } 74 //已找到 75 return hv; 76 } 77 return -1;//表示未找到 78 } 79 80 bool hashTable::find(const obj& o) { 81 return findEle(o.key) != -1; 82 } 83 84 bool hashTable::remove(const obj&o) { 85 int hv = findEle(o.key); 86 if (hv == -1)return false; 87 88 _table[hv].s = DELETE; 89 num--; 90 91 return true; 92 } 93 94 void hashTable::chk_memory() { 95 if (num + 2 >= size()) { 96 int newsize = (num == 0 ? 3 : 2 * num); 97 newsize = nextprime(newsize); 98 99 vector<obj> oldtable = _table; 100 _table.resize(newsize); 101 for (int i = 0;i < _table.size();i++)_table[i].s = EMPTY; 102 for (int i = 0;i < oldtable.size();i++) 103 if (oldtable[i].s == EXIST)_table[i] = oldtable[i]; 104 } 105 } 106 107 bool hashTable::insert(const obj&o) { 108 if (find(o)) { 109 cout << "已存在该键值,插入失败!" << endl; 110 return false; 111 } 112 113 chk_memory();//保证有内存可插入 114 115 int hv = myhash(o.key) % size(); 116 while (_table[hv].s == EXIST) { 117 hv++; 118 if (hv == size())hv = 0; 119 } 120 121 num++; 122 _table[hv].key = o.key; 123 _table[hv].s = EXIST; 124 return true; 125 } 126 127 int main(void) { 128 hashTable h; 129 Node n(string("xixi")); 130 h.insert(n); 131 h.insert(n); 132 if (h.find(n))cout << "hhh" << endl; 133 h.remove(n); 134 if (h.find(n))cout << "hhh" << endl; 135 return 0; 136 }
没有经过严格测试,代码如上