commit
e14fd87ddb
186
c-cpp/18_hashtable/hashtable.c
Normal file
186
c-cpp/18_hashtable/hashtable.c
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
83
c-cpp/23_binarytree/binarytree.c
Normal file
83
c-cpp/23_binarytree/binarytree.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user