What is the printed state of the HashMap after inserting three key-value pairs?
class HashMap { private: static const int SIZE = 5; std::pair<int, int> table[SIZE]; bool occupied[SIZE]; public: HashMap() { for (int i = 0; i < SIZE; i++) { occupied[i] = false; } } int hash(int key) { return key % SIZE; } void insert(int key, int value) { int idx = hash(key); while (occupied[idx]) { idx = (idx + 1) % SIZE; } table[idx] = {key, value}; occupied[idx] = true; } void print() { for (int i = 0; i < SIZE; i++) { if (occupied[i]) { std::cout << table[i].first << ":" << table[i].second << " "; } else { std::cout << "_ "; } } std::cout << std::endl; } }; int main() { HashMap map; map.insert(1, 10); map.insert(6, 20); map.insert(11, 30); map.print(); return 0; }
Remember the hash function is key % 5 and collision is resolved by linear probing.
Keys 1, 6, and 11 all hash to index 1 (1 % 5 = 1, 6 % 5 = 1, 11 % 5 = 1). Insert 1 at index 1. For 6, index 1 is occupied, so move to index 2. For 11, indexes 1 and 2 are occupied, so move to index 3.
Which collision resolution technique is used in the following HashMap implementation?
void insert(int key, int value) { int idx = hash(key); while (occupied[idx]) { idx = (idx + 1) % SIZE; } table[idx] = {key, value}; occupied[idx] = true; }
Look at how the index is updated when a collision occurs.
The code increments the index by 1 each time a collision happens, wrapping around the table. This is linear probing.
What error will occur when running the search method below if the key is not present?
int search(int key) { int idx = hash(key); while (occupied[idx]) { if (table[idx].first == key) { return table[idx].second; } idx = (idx + 1) % SIZE; } return -1; } // Assume SIZE = 5 and occupied array is properly maintained.
Consider what happens when the key is not in the table and the loop condition.
The loop stops when it finds an empty slot (occupied[idx] == false), so it returns -1 correctly if the key is not found.
What is the printed state of the HashMap after deleting key 6 and inserting key 16 with value 160?
class HashMap { private: static const int SIZE = 5; std::pair<int, int> table[SIZE]; bool occupied[SIZE]; bool deleted[SIZE]; public: HashMap() { for (int i = 0; i < SIZE; i++) { occupied[i] = false; deleted[i] = false; } } int hash(int key) { return key % SIZE; } void insert(int key, int value) { int idx = hash(key); while (occupied[idx] && !deleted[idx]) { idx = (idx + 1) % SIZE; } table[idx] = {key, value}; occupied[idx] = true; deleted[idx] = false; } void remove(int key) { int idx = hash(key); while (occupied[idx]) { if (!deleted[idx] && table[idx].first == key) { deleted[idx] = true; return; } idx = (idx + 1) % SIZE; } } void print() { for (int i = 0; i < SIZE; i++) { if (occupied[i] && !deleted[i]) { std::cout << table[i].first << ":" << table[i].second << " "; } else { std::cout << "_ "; } } std::cout << std::endl; } }; int main() { HashMap map; map.insert(1, 10); map.insert(6, 20); map.insert(11, 30); map.remove(6); map.insert(16, 160); map.print(); return 0; }
Remember that deleted slots can be reused for insertion.
Key 6 was at index 2 and marked deleted. Inserting 16 hashes to index 1, which is occupied, then index 2 is deleted and reused for 16.
Given the following sequence of operations on an empty HashMap of size 7, what is the final printed state?
Operations:
- insert(3, 30)
- insert(10, 100)
- insert(17, 170)
- remove(10)
- insert(24, 240)
- insert(31, 310)
- remove(3)
- insert(38, 380)
class HashMap { private: static const int SIZE = 7; std::pair<int, int> table[SIZE]; bool occupied[SIZE]; bool deleted[SIZE]; public: HashMap() { for (int i = 0; i < SIZE; i++) { occupied[i] = false; deleted[i] = false; } } int hash(int key) { return key % SIZE; } void insert(int key, int value) { int idx = hash(key); while (occupied[idx] && !deleted[idx]) { idx = (idx + 1) % SIZE; } table[idx] = {key, value}; occupied[idx] = true; deleted[idx] = false; } void remove(int key) { int idx = hash(key); while (occupied[idx]) { if (!deleted[idx] && table[idx].first == key) { deleted[idx] = true; return; } idx = (idx + 1) % SIZE; } } void print() { for (int i = 0; i < SIZE; i++) { if (occupied[i] && !deleted[i]) { std::cout << table[i].first << ":" << table[i].second << " "; } else { std::cout << "_ "; } } std::cout << std::endl; } }; int main() { HashMap map; map.insert(3, 30); map.insert(10, 100); map.insert(17, 170); map.remove(10); map.insert(24, 240); map.insert(31, 310); map.remove(3); map.insert(38, 380); map.print(); return 0; }
Trace each insertion and removal carefully, remembering linear probing and lazy deletion.
Keys hash as follows: 3->3, 10->3, 17->3, 24->3, 31->3, 38->3. Insertions and removals shift keys forward. After removals and insertions, the final occupied and non-deleted slots are at indices 1,2,3,5 with keys 24,31,38,17 respectively.
