#ifndef HashTable_H #define HashTable_H #include template class HashTable { struct TableEntry { Key k; Value v; bool used; }; class HTIterator { size_t entries_left; struct TableEntry *table; public: HTIterator(TableEntry *t, size_t el) { table = t; entries_left = el; while(!table[entries_left-1].used && entries_left > 0) entries_left--; } HTIterator operator++(){ if(entries_left == 0) return *this; entries_left--; if(!entries_left) return *this; while(!table[entries_left-1].used){ entries_left--; if(!entries_left) return *this; } return *this; } bool operator!=(const HTIterator& other){ return other.entries_left != entries_left; } Key& operator*(){ return table[entries_left-1].k; } }; struct TableEntry *table; size_t capacity = 10; size_t items = 0; public: HashTable(){ table = (struct TableEntry*)malloc(sizeof(struct TableEntry) * 10); memset(table, 0, (sizeof(struct TableEntry) * 10)); } size_t get_items(){ return items; } HTIterator begin(){ return HTIterator(table, capacity); } HTIterator end(){ return HTIterator(table, 0); } bool contains(Key k){ size_t hv = data_hash(k) % capacity; // Retreive an existing entry from the table while(table[hv].used){ if(table[hv].k == k) return true; hv++; if(hv >= capacity) hv -= capacity; // TODO What if the table is actually all the way full? } return false; } Value& operator[] (Key k){ size_t hv = data_hash(k) % capacity; // Retreive an existing entry from the table while(table[hv].used){ if(table[hv].k == k) return table[hv].v; hv++; if(hv >= capacity) hv -= capacity; // TODO What if the table is actually all the way full? // Answer: It's not. We resize it when it's half full } // If we're here, then we didn't find anything // The user wants to add it! // See how full the table is if(items > capacity/2){ // Resize the table size_t new_capacity = capacity*2; struct TableEntry *new_table = (struct TableEntry*)malloc(sizeof(struct TableEntry) * new_capacity); memset(new_table, 0, (sizeof(struct TableEntry) * new_capacity)); for(size_t i = 0; i < capacity; i++){ // each item in the old table if(!table[i].used) continue; //Find the spot for a key an existing entry from the table //The next few lines insert a new value v at position k Key k = table[i].k; // The one from the old table Value v = table[i].v; // The one from the old table, again size_t hv = data_hash(k) % new_capacity; while(new_table[hv].used){ hv++; if(hv >= new_capacity) hv -= new_capacity; } new_table[hv] = table[i]; } free(table); table = new_table; capacity = new_capacity; } // Add a new entry to the table (as in, we didn't find it) table[hv].k = k; table[hv].used = true; items++; return table[hv].v; } ~HashTable(){ free(table); } // Expected use: our_hash_table[key] = value // Like this: our_hash_table["fish"] = 400; }; #endif