From 7119f47c9e10f4ce4866b708db5324fddc5e7f27 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Mon, 5 Nov 2018 11:29:38 +0800 Subject: [PATCH 1/2] hash table in c --- c-cpp/18_hashtable/hashtable.c | 186 +++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 c-cpp/18_hashtable/hashtable.c diff --git a/c-cpp/18_hashtable/hashtable.c b/c-cpp/18_hashtable/hashtable.c new file mode 100644 index 0000000..03f7035 --- /dev/null +++ b/c-cpp/18_hashtable/hashtable.c @@ -0,0 +1,186 @@ +#include +#include +#include +#include +#include + +/* One implementation of hash table with linear probing. */ + +#define HASH_SHIFT 4 +#define HASH_SIZE (1 << HASH_SHIFT) +#define HASH_MASK (HASH_SIZE - 1) + +struct hash_table { + unsigned int used; + unsigned long entry[HASH_SIZE]; +}; + +void hash_table_reset(struct hash_table *table) +{ + int i; + + table->used = 0; + for (i = 0; i < HASH_SIZE; i++) + table->entry[i] = ~0; +} + +unsigned int hash_function(unsigned long value) +{ + return value & HASH_MASK; +} + +void dump_hash_table(struct hash_table *table) +{ + int i; + + for (i = 0; i < HASH_SIZE; i++) { + if (table->entry[i] == ~0) + printf("%2u: nil \n", i); + else + printf("%2u:%10lu -> %2u\n", + i, table->entry[i], + hash_function(table->entry[i])); + } +} + +void hash_function_test() +{ + int i; + + srandom(time(NULL)); + + for (i = 0; i < 10; i++) { + unsigned long val = random(); + printf("%10lu -> %2u\n", val, hash_function(val));; + } +} + +unsigned int next_probe(unsigned int prev_key) +{ + return (prev_key + 1) & HASH_MASK; +} + +void next_probe_test() +{ + int i; + unsigned int key1, key2; + + key1 = 0; + for (i = 0; i < HASH_SIZE; i++) { + key2 = next_probe(key1); + printf("%2u -> %2u\n", key1, key2); + key1 = key2; + } +} + +void hash_table_add(struct hash_table *table, unsigned long value) +{ + unsigned int key = hash_function(value); + + if (table->used >= HASH_SIZE) + return; + + while (table->entry[key] != ~0) + key = next_probe(key); + + table->entry[key] = value; + table->used++; +} + +unsigned int hash_table_slot(struct hash_table *table, unsigned long value) +{ + int i; + unsigned int key = hash_function(value); + + for (i = 0; i < HASH_SIZE; i++) { + if (table->entry[key] == value || table->entry[key] == ~0) + break; + key = next_probe(key); + } + + return key; +} + +bool hash_table_find(struct hash_table *table, unsigned long value) +{ + return table->entry[hash_table_slot(table, value)] == value; +} + +void hash_table_del(struct hash_table *table, unsigned long value) +{ + unsigned int i, j, k; + + if (!hash_table_find(table, value)) + return; + + i = j = hash_table_slot(table, value); + + while (true) { + table->entry[i] = ~0; + + do { + j = next_probe(j); + if (table->entry[j] == ~0) + return; + k = hash_function(table->entry[j]); + } while ((i <= j) ? (i < k && k <= j) : (i < k || k <= j)); + + table->entry[i] = table->entry[j]; + i = j; + } + table->used++; +} + +void hash_table_add_test() +{ + struct hash_table table; + + hash_table_reset(&table); + hash_table_add(&table, 87645); + + printf("Table has%s 87645\n", + hash_table_find(&table, 87645) ? "":"n't"); + printf("Table has%s 87647\n", + hash_table_find(&table, 87647) ? "":"n't"); +} + +void hash_table_del_test1() +{ + struct hash_table table; + + hash_table_reset(&table); + hash_table_add(&table, 0x1ff0); + hash_table_add(&table, 0x2ff0); + hash_table_add(&table, 0x3ff0); + dump_hash_table(&table); + + printf("=== Remove 0x1ff0\n"); + hash_table_del(&table, 0x1ff0); + dump_hash_table(&table); +} + +void hash_table_del_test2() +{ + struct hash_table table; + + hash_table_reset(&table); + hash_table_add(&table, 0x1ff0); + hash_table_add(&table, 0x1ff1); + hash_table_add(&table, 0x1ff2); + hash_table_add(&table, 0x2ff0); + dump_hash_table(&table); + + printf("=== Remove 0x1ff0\n"); + hash_table_del(&table, 0x1ff0); + dump_hash_table(&table); +} + +int main() +{ + //hash_function_test(); + //next_probe_test(); + //hash_table_add_test(); + hash_table_del_test2(); + + return 0; +} From f41d01589c5da454cb271c6920fc66dd563c644e Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Mon, 12 Nov 2018 10:08:38 +0800 Subject: [PATCH 2/2] binary tree in array --- c-cpp/23_binarytree/binarytree.c | 83 ++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 c-cpp/23_binarytree/binarytree.c diff --git a/c-cpp/23_binarytree/binarytree.c b/c-cpp/23_binarytree/binarytree.c new file mode 100644 index 0000000..4143cd1 --- /dev/null +++ b/c-cpp/23_binarytree/binarytree.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +/* Implement binary tree in array */ + +#define MAX_TREE_NODES (1 << 8) + +struct node { + int data; +}; + +struct binary_tree { + union { + unsigned long nodes; + struct node *n[MAX_TREE_NODES]; + }; +}; + +void init_binary_tree(struct binary_tree *tree) +{ + int i; + + for(i = 0; i < MAX_TREE_NODES; i++) { + tree->n[i] = NULL; + } +} + +struct node* create_node(int data) +{ + struct node* n; + + n = malloc(sizeof(struct node)); + + if (n) + n->data = data; + + return n; +} + +void fake_a_tree(struct binary_tree* tree) +{ + /* data is in ordered */ + int i, data[10] = {7, 4, 9, 2, 6, 8, 10, 1, 3, 5}; + + init_binary_tree(tree); + + /* root start at 1 */ + for (i = 0; i < 10; i++) + tree->n[i+1] = create_node(data[i]); + + tree->nodes = 10; +} + +void _in_order(struct binary_tree* tree, int index) +{ + if (!tree->n[index]) + return; + + /* left child at (index << 1) */ + _in_order(tree, index << 1); + + printf("[%2d]: %4d\n", index, tree->n[index]->data); + + /* right child at (index << 1) + 1 */ + _in_order(tree, (index << 1) + 1); +} + +void in_order(struct binary_tree* tree) +{ + _in_order(tree, 1); +} + +int main() +{ + struct binary_tree tree; + + fake_a_tree(&tree); + in_order(&tree); + return 0; +}