Compare commits
3 Commits
13932df1a8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 488ea7960b | |||
| f3b0be9500 | |||
| e819633ba0 |
113
c/hash-table.c
113
c/hash-table.c
@@ -2,19 +2,38 @@
|
||||
#include <stdlib.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 {
|
||||
char *data[16];
|
||||
Node *data[MAX_HASH_TABLE_SIZE];
|
||||
} HashTable;
|
||||
|
||||
HashTable *new_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;
|
||||
}
|
||||
|
||||
return (ht);
|
||||
}
|
||||
|
||||
Node *new_node() {
|
||||
Node *node = malloc(sizeof(Node));
|
||||
node->next = NULL;
|
||||
|
||||
return (node);
|
||||
}
|
||||
|
||||
int get_index_for_letter(char letter) {
|
||||
if (letter >= 'a' && letter <= 'z') {
|
||||
return (letter - 'a') + 1;
|
||||
@@ -35,35 +54,83 @@ int hash(char *word) {
|
||||
return accum % 16;
|
||||
}
|
||||
|
||||
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);
|
||||
KV *find_KV_in_ht(HashTable h, char *key) {
|
||||
for (size_t i = 0; i < MAX_HASH_TABLE_SIZE; i++) {
|
||||
if ((h.data[i] != NULL) && (strcmp(h.data[i]->kv.key, key) == 0)) {
|
||||
return (&h.data[i]->kv);
|
||||
}
|
||||
}
|
||||
|
||||
h->data[hashed_key] = value;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void delete(HashTable *h, char *key) {
|
||||
int hashed_key = hash(key);
|
||||
h->data[hashed_key] = NULL;
|
||||
char *get_value(HashTable ht, char *key) {
|
||||
int hash_key = hash(key);
|
||||
|
||||
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() {
|
||||
HashTable *hash_table = new_hashtable();
|
||||
char *key = "hello";
|
||||
insert(hash_table, key, "world");
|
||||
insert(hash_table, "hlleo", "world");
|
||||
char *res = get(hash_table, "hello");
|
||||
HashTable *h = new_hashtable();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
38
ts/bfs.test.ts
Normal file
38
ts/bfs.test.ts
Normal 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
47
ts/tree.ts
Normal 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
44
ts/tree_traversal.test.ts
Normal 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,
|
||||
]);
|
||||
});
|
||||
Reference in New Issue
Block a user