Compare commits

..

3 Commits

4 changed files with 219 additions and 23 deletions

View File

@@ -2,19 +2,38 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define MAX_HASH_TABLE_SIZE 16
typedef struct KV {
char *key;
char *value;
} KV;
typedef struct Node {
KV kv;
struct Node *next;
} Node;
typedef struct HashTable { typedef struct HashTable {
char *data[16]; Node *data[MAX_HASH_TABLE_SIZE];
} HashTable; } HashTable;
HashTable *new_hashtable() { HashTable *new_hashtable() {
HashTable *ht = malloc(sizeof(HashTable)); HashTable *ht = malloc(sizeof(HashTable));
for (int i = 0; i < 16; i++) { for (int i = 0; i < MAX_HASH_TABLE_SIZE; i++) {
ht->data[i] = NULL; ht->data[i] = NULL;
} }
return (ht); return (ht);
} }
Node *new_node() {
Node *node = malloc(sizeof(Node));
node->next = NULL;
return (node);
}
int get_index_for_letter(char letter) { int get_index_for_letter(char letter) {
if (letter >= 'a' && letter <= 'z') { if (letter >= 'a' && letter <= 'z') {
return (letter - 'a') + 1; return (letter - 'a') + 1;
@@ -35,35 +54,83 @@ int hash(char *word) {
return accum % 16; return accum % 16;
} }
char *get(HashTable *h, char *key) { KV *find_KV_in_ht(HashTable h, char *key) {
int hash_val = hash(key); for (size_t i = 0; i < MAX_HASH_TABLE_SIZE; i++) {
return h->data[hash_val]; if ((h.data[i] != NULL) && (strcmp(h.data[i]->kv.key, key) == 0)) {
} return (&h.data[i]->kv);
}
void insert(HashTable *h, char *key, char *value) {
int hashed_key = hash(key);
if (h->data[hashed_key] != NULL) {
fprintf(stderr, "ERROR: collision!");
exit(1);
} }
h->data[hashed_key] = value; return (NULL);
} }
void delete(HashTable *h, char *key) { char *get_value(HashTable ht, char *key) {
int hashed_key = hash(key); int hash_key = hash(key);
h->data[hashed_key] = NULL;
Node *node_at_hash = ht.data[hash_key];
if (node_at_hash == NULL) {
fprintf(stderr, "ERROR: key not found in hashtable");
return;
}
// if next is NULL then this is the only at this hash so just return it
if (node_at_hash->next == NULL) {
return node_at_hash->kv.value;
}
return kv->value;
} }
void insert_kv(HashTable *ht, char *key, char *value) {
int hashed_key = hash(key);
Node *current = ht->data[hashed_key];
while (current) {
if (strcmp(current->kv.key, key) == 0) {
current->kv.value = value;
return;
}
current = current->next;
}
Node *new = new_node();
new->kv.key = key;
new->kv.value = value;
new->next = current;
ht->data[hashed_key] = new;
}
// char *get(HashTable *h, char *key) {
// int hash_val = hash(key);
// return h->data[hash_val];
// }
// void insert(HashTable *h, char *key, char *value) {
// int hashed_key = hash(key);
// if (h->data[hashed_key] != NULL) {
// fprintf(stderr, "ERROR: collision!");
// exit(1);
// }
// h->data[hashed_key] = value;
// }
// void delete(HashTable *h, char *key) {
// int hashed_key = hash(key);
// h->data[hashed_key] = NULL;
// }
int main() { int main() {
HashTable *hash_table = new_hashtable(); HashTable *h = new_hashtable();
char *key = "hello";
insert(hash_table, key, "world");
insert(hash_table, "hlleo", "world");
char *res = get(hash_table, "hello");
printf("the value at key '%s' is '%s'", key, res); // test
insert_kv(h, "hello", "world");
char *result = get_value(*h, "hello");
printf("the value corresponding to the key 'hello' is: '%s'", result);
return 0; return 0;
} }

38
ts/bfs.test.ts Normal file
View File

@@ -0,0 +1,38 @@
import { tree } from "./tree"
type BinaryNode<T> = {
value: T;
left: BinaryNode<T> | null;
right: BinaryNode<T> | null;
};
function bfs(head: BinaryNode<number> | null, needle: number): boolean {
const q: (BinaryNode<number> | null)[] = [head];
while (q.length) {
const current = q.shift() as BinaryNode<number>;
if (current.value === needle) {
return true;
}
if (current.left) {
q.push(current.left);
}
if (current.right) {
q.push(current.right);
}
}
return false;
}
test("bfs search works a number of values", function () {
expect(bfs(tree, 20)).toEqual(true);
expect(bfs(tree, -20)).toEqual(false);
expect(bfs(tree, 10)).toEqual(true);
expect(bfs(tree, 7)).toEqual(true);
})

47
ts/tree.ts Normal file
View File

@@ -0,0 +1,47 @@
type BinaryNode<T> = {
value: T;
left: BinaryNode<T> | null;
right: BinaryNode<T> | null;
};
export const tree: BinaryNode<number> = {
value: 20,
right: {
value: 50,
right: {
value: 100,
right: null,
left: null,
},
left: {
value: 30,
right: {
value: 45,
right: null,
left: null,
},
left: {
value: 29,
right: null,
left: null,
}
},
},
left: {
value: 10,
right: {
value: 15,
right: null,
left: null,
},
left: {
value: 5,
right: {
value: 7,
right: null,
left: null,
},
left: null,
}
}
};

44
ts/tree_traversal.test.ts Normal file
View File

@@ -0,0 +1,44 @@
import { tree } from "./tree"
type BinaryNode<T> = {
value: T;
left: BinaryNode<T> | null;
right: BinaryNode<T> | null;
};
// pre order
function walk(current: BinaryNode<number> | null, path: number[]): number[] {
if (!current) {
return path;
}
path.push(current.value);
walk(current.left, path);
walk(current.right, path);
return path;
}
function pre_order_search(head: BinaryNode<number>): number[] {
const path: number[] = [];
walk(head, path);
return path;
}
test("Pre order", function () {
expect(pre_order_search(tree)).toEqual([
20,
10,
5,
7,
15,
50,
30,
29,
45,
100,
]);
});