Foreword
记录2022 winter的CS106B Assignment7
Enumerations Warmup
熟悉一下枚举类型
Linear Probing Warmup
熟悉一下线性探测哈希
Implementing Linear Probing
实现LinearProbingHashTable.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
   | #include "LinearProbingHashTable.h" using namespace std;
  LinearProbingHashTable::LinearProbingHashTable(HashFunction<string> hashFn) {     myHash = hashFn;     allocatedSize = hashFn.numSlots();     elems = new Slot[allocatedSize];     for (int i = 0; i < allocatedSize; ++i) {         elems[i].type = SlotType::EMPTY;     } }
  LinearProbingHashTable::~LinearProbingHashTable() {     delete[] elems; }
  int LinearProbingHashTable::size() const {     return logicalSize; }
  bool LinearProbingHashTable::isEmpty() const {     return logicalSize == 0; }
  bool LinearProbingHashTable::insert(const string& elem) {     int hash = myHash(elem) % allocatedSize;     while (true) {         if (logicalSize == allocatedSize) {             return false;         } else if (elems[hash].type == SlotType::EMPTY) {             elems[hash].value = elem;             elems[hash].type = SlotType::FILLED;             ++logicalSize;             return true;         } else if (elems[hash].type == SlotType::FILLED) {             if (elems[hash].value == elem) {                 return false;             }         } else if (elems[hash].type == SlotType::TOMBSTONE) {             if (!contains(elem)) {                 elems[hash].value = elem;                 elems[hash].type = SlotType::FILLED;                 ++logicalSize;                 return true;             }         }         hash = (hash + 1) % allocatedSize;     } }
  bool LinearProbingHashTable::contains(const string& elem) const {     int hash = myHash(elem) % allocatedSize;     int T = logicalSize;     while (T) {         if (elems[hash].type == SlotType::FILLED && elems[hash].value == elem) {             return true;         } else if (elems[hash].type == SlotType::EMPTY) {             break;         } else if (elems[hash].type == SlotType::FILLED) {             --T;         }         hash = (hash + 1) % allocatedSize;     }     return false; }
  bool LinearProbingHashTable::remove(const string& elem) {     if (!contains(elem)) {         return false;     }     int hash = myHash(elem) % allocatedSize;     int T = logicalSize;     while (T) {         if (elems[hash].type == SlotType::EMPTY) {             return false;         } else if (elems[hash].type == SlotType::FILLED) {             if (elems[hash].value == elem) {                 --logicalSize;                 elems[hash].value.clear();                 elems[hash].type = SlotType::TOMBSTONE;                 return true;             }             --T;         }         hash = (hash + 1) % allocatedSize;     }     return false; }
   | 
 
Robin Hood Warmup
熟悉一下Robin Hood哈希
主要思想是让每个key离它的home slot尽量近
Robin Hood Hashing
实现RobinHoodHashTable.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
   | #include "RobinHoodHashTable.h" using namespace std;
  RobinHoodHashTable::RobinHoodHashTable(HashFunction<string> hashFn) {     myHash = hashFn;     allocatedSize = hashFn.numSlots();     elems = new Slot[allocatedSize];     for (int i = 0; i < allocatedSize; ++i) {         elems[i].distance = EMPTY_SLOT;     } }
  RobinHoodHashTable::~RobinHoodHashTable() {     delete[] elems; }
  int RobinHoodHashTable::size() const {     return logicalSize; }
  bool RobinHoodHashTable::isEmpty() const {     return logicalSize == 0; }
  bool RobinHoodHashTable::insert(const string& elem) {     if (contains(elem) || logicalSize == allocatedSize) {         return false;     }     int hash = myHash(elem) % allocatedSize;     int dis = 0;     while (true) {         if (elems[hash].distance == EMPTY_SLOT) {             ++logicalSize;             elems[hash].value = elem;             elems[hash].distance = dis;             return true;         } else if (elems[hash].distance < dis) {             auto hostage = elems[hash].value;             elems[hash].value = elem;             elems[hash].distance = dis;             insert(hostage);             return true;         }         ++dis;         hash = (hash + 1) % allocatedSize;     }     return false; }
  bool RobinHoodHashTable::contains(const string& elem) const {     if (logicalSize == 0) {         return false;     }     int hash = myHash(elem) % allocatedSize;     int dis = 0;     while (true) {         if (elems[hash].distance == EMPTY_SLOT) {             return false;         } else if (elems[hash].value == elem) {             return true;         } else if (elems[hash].distance < dis) {             return false;         }         ++dis;         hash = (hash + 1) % allocatedSize;     } }
  bool RobinHoodHashTable::remove(const string& elem) {     if (!contains(elem) || logicalSize == 0) {         return false;     }     int hash = myHash(elem) % allocatedSize;     while (true) {         if (elems[hash].value == elem) {             elems[hash].distance = EMPTY_SLOT;             elems[hash].value.clear();             --logicalSize;             while (true) {                 int nxt = (hash + 1) % allocatedSize;                 if (elems[nxt].distance == EMPTY_SLOT || elems[nxt].distance == 0) {                     elems[hash].distance = EMPTY_SLOT;                     elems[hash].value.clear();                     break;                 }                 elems[hash].value = elems[nxt].value;                 elems[hash].distance = elems[nxt].distance - 1;                 hash = nxt;             }             return true;         }         hash = (hash + 1) % allocatedSize;     }     return false; }
   | 
 
效果
