data-structures · intermediate · ~40 min
Hash table from scratch: hash function, chaining, deletion.
Build a string-keyed, int-valued key-value store using a chained hash table.
Implement the following API using a hash table with separate chaining (a linked list of entries per bucket).
typedef struct kv kv_t;
kv_t *kv_create(int n_buckets);
void kv_set(kv_t *kv, const char *key, int value);
int kv_get(kv_t *kv, const char *key, int *out_value); /* 1=found, 0=missing */
int kv_del(kv_t *kv, const char *key); /* 1=removed, 0=missing */
void kv_destroy(kv_t *kv);
n_buckets: the number of hash buckets (> 0).key: a lowercase ASCII string, up to 64 bytes (the store keeps its own copy).value: the int to associate with the key.out_value: where kv_get writes the found value.kv_set: nothing; inserts a new key or updates an existing one (no duplicates).kv_get: 1 and writes the value through out_value if found; 0 if missing.kv_del: 1 if a key was removed, 0 if it was not present.kv_create(4)
kv_set("foo", 42); kv_set("bar", 100)
kv_get("foo", &v) -> 1, v == 42
kv_set("foo", 999) (update, not a duplicate)
kv_get("foo", &v) -> 1, v == 999
kv_del("bar") -> 1
kv_get("bar", &v) -> 0
kv_del("none") -> 0
strdup'd key on delete and destroy.A key-value store is the universal data structure. Redis is a key-value store. Memcached is a key-value store. Browser localStorage is a key-value store. Building one from scratch reveals what hash maps actually buy you.
n_buckets > 0; lowercase ASCII keys up to 64 bytes; int values; up to 10000 ops.
See the API: get/del return 1/0; get writes through out_value.
Use FNV-1a or djb2 for hashing. Use linked-list chains per bucket.
typedef struct kv kv_t;
kv_t *kv_create(int n_buckets);
void kv_set(kv_t *kv, const char *key, int value);
int kv_get(kv_t *kv, const char *key, int *out_value);
int kv_del(kv_t *kv, const char *key);
void kv_destroy(kv_t *kv);
Forgetting to update size on delete; comparing pointers instead of strcmp; not freeing key strdups on destroy.
Set then set on same key (update, no duplicate). Delete of missing key. Get of missing key.
Average O(1); worst-case O(n) with adversarial hash.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.