Skip to content

Commit

Permalink
Minor hash tweaks, new binary tree interface (incomplete)
Browse files Browse the repository at this point in the history
  • Loading branch information
fubarwrangler committed Mar 5, 2012
1 parent 0ec2b4e commit 7a2a932
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 7 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -7,3 +7,4 @@ include_directories(include)
add_subdirectory(list)
add_subdirectory(tests)
add_subdirectory(hash)
add_subdirectory(tree)
8 changes: 4 additions & 4 deletions hash/hash.c
Expand Up @@ -9,7 +9,6 @@
hash_table *hash_init(hash_fn_t hash_fn, size_t initial_size)
{
hash_table *h = malloc(sizeof(hash_table));
size_t i;

if(h != NULL) {
/* Did we supply a hash function? */
Expand All @@ -18,10 +17,11 @@ hash_table *hash_init(hash_fn_t hash_fn, size_t initial_size)
h->size = (initial_size == 0) ? INIT_HASH_TBL_SIZE : initial_size;
h->nelm = 0;
h->flags = 0;
h->buckets = calloc(h->size, sizeof(bucket_data *));
h->g_trigger = 1.0;
h->g_factor = 2.0;
h->g_trigger = 2.0;
h->buckets = calloc(h->size, sizeof(bucket_data *));
if(h->buckets != NULL) {
size_t i;
for(i = 0; i < h->size; i++)
h->buckets[i] = NULL;
return h;
Expand Down Expand Up @@ -174,7 +174,7 @@ int hash_resize(hash_table *h, size_t newsize)
return 1;
for(i = 0; i < h->size; i++) {
b = h->buckets[i];
/* For each old bucket, insert into new bucket list(s) */
/* For each old bucket item, insert into correct new bucket */
while(b) {
unsigned int idx = h->hash_fn(b->key) % newsize;
next = b->next;
Expand Down
12 changes: 9 additions & 3 deletions include/hash.h
Expand Up @@ -9,8 +9,8 @@
/* Hash function type -- maps strings to unsigned ints */
typedef unsigned int (*hash_fn_t)(const char *);

#define HASH_AUTOFREE_ 32 /* Call free() on each value on destroy */
#define HASH_AUTOGROW_ 64 /* Grow hash via rehash automatically */
#define HASH_AUTOFREE_ 0x01 /* Call free() on each value on destroy */
#define HASH_AUTOGROW_ 0x02 /* Grow hash via rehash automatically */

typedef struct _bucket_data
{
Expand Down Expand Up @@ -58,6 +58,13 @@ inline void hash_set_autofree(hash_table *h)
h->flags |= HASH_AUTOFREE_;
}

/**
* hash_set_autogrow() -- enable and set parameters for automatic re-hash on
* insert if the table grows too large
* @h -- hash table to operate on
* @trigger -- nelm/nbuckets ratio to trigger a growth
* @factor -- scaling factor to grow, new_size = k * old_size, k > 1.0
*/
inline void hash_set_autogrow(hash_table *h, float trigger, float factor)
{
if(trigger > 0.0 && factor > 1.0) {
Expand All @@ -77,7 +84,6 @@ inline void hash_unset_autogrow(hash_table *h)
h->flags &= ~HASH_AUTOGROW_;
}


/**
* hash_init() -- initalize a new hash table with hash function @hash_fn
*
Expand Down
25 changes: 25 additions & 0 deletions include/tree.h
@@ -0,0 +1,25 @@
#ifndef TREE_H_
#define TREE_H_

typedef int (*bintree_cmp)(void *, void *);

struct btnode {
struct btnode *left;
struct btnode *right;
void *data;
};

struct binary_tree {
struct btnode *root;
bintree_cmp cmp_fn;
};

struct binary_tree *init_bintree(bintree_cmp cmp_fn);

void destroy_bintree(struct binary_tree *bt);

void *bintree_search(struct binary_tree *bt, void *data);

int bintree_insert(struct binary_tree *bt, void *data);

#endif /* TREE_H_ */
4 changes: 4 additions & 0 deletions tests/CMakeLists.txt
Expand Up @@ -13,3 +13,7 @@ target_link_libraries(stack_test llist)

add_executable(hash_test hash_test.c)
target_link_libraries(hash_test hash)

add_executable(tree_test tree_test.c)
target_link_libraries(tree_test bintree)

72 changes: 72 additions & 0 deletions tests/tree_test.c
@@ -0,0 +1,72 @@
#include <stdio.h>
#include <stdlib.h>

#include "tree.h"


int intcmp(void *a, void *b) {
return *(int *)a - *(int *)b;
}

void inorder(struct btnode *b)
{
if(b == NULL)
return;
inorder(b->left);
printf("Node at %p: %d (left -> %p, right -> %p)\n",
b, *(int *)(b->data), b->left, b->right);
inorder(b->right);
}

void postorder(struct btnode *b)
{
if(b == NULL)
return;
postorder(b->left);
postorder(b->right);
printf("Node at %p: %d (left -> %p, right -> %p)\n",
b, *(int *)(b->data), b->left, b->right);
}

void preorder(struct btnode *b)
{
if(b == NULL)
return;
printf("Node at %p: %d (left -> %p, right -> %p)\n",
b, *(int *)(b->data), b->left, b->right);
preorder(b->left);
preorder(b->right);
}

void inorder_dot(struct btnode *b)
{
if(b == NULL)
return;
inorder_dot(b->left);
if(b->left)
printf("\t%d -> %d\n", *(int *)b->data, *(int *)b->left->data);
if(b->right)
printf("\t%d -> %d\n", *(int *)b->data, *(int *)b->right->data);
inorder_dot(b->right);
}

int main(int argc, char *argv[])
{
int a[] = {5, 31, 2, 9, 24, 12, 7, 19, 30, 35, 2, 4, 0};
int *p = a;
struct binary_tree *bt;

bt = init_bintree(&intcmp);

while(*p)
bintree_insert(bt, p++);

puts("digraph tree {");
inorder_dot(bt->root);
puts("}\n");

destroy_bintree(bt);

return 0;

}
2 changes: 2 additions & 0 deletions tree/CMakeLists.txt
@@ -0,0 +1,2 @@

add_library(bintree SHARED tree.c)
75 changes: 75 additions & 0 deletions tree/tree.c
@@ -0,0 +1,75 @@
#include <stdio.h>
#include <stdlib.h>

#include "tree.h"


struct binary_tree *init_bintree(bintree_cmp cmp_fn)
{
struct binary_tree *b = malloc(sizeof(struct binary_tree));
if(b != NULL) {
b->cmp_fn = cmp_fn;
b->root = NULL;
}
return b;
}

static void freetree(struct btnode *p)
{
if(p == NULL)
return;
freetree(p->left);
freetree(p->right);
free(p);
}

void destroy_bintree(struct binary_tree *bt)
{
struct btnode *n = bt->root;
freetree(bt->root);
//free(bt->root);
free(bt);
}

static struct btnode **btn_srch(struct binary_tree *bt, void *data)
{
struct btnode **n = &(bt->root);
int res;

while(*n != NULL) {
res = bt->cmp_fn(data, (*n)->data);
if(res < 0) {
n = &(*n)->left;
} else if (res > 0) {
n = &(*n)->right;
} else {
break;
}
}
return n;
}

void *bintree_search(struct binary_tree *bt, void *data)
{
struct btnode **n = btn_srch(bt, data);
if(*n != NULL)
return (*n)->data;
else
return *n;
}

int bintree_insert(struct binary_tree *bt, void *data)
{
struct btnode **n = btn_srch(bt, data);
if(*n == NULL) {
*n = malloc(sizeof(struct btnode));
if(*n == NULL)
return -1;
(*n)->left = (*n)->right = NULL;
(*n)->data = data;
return 0;
}
return 1;
}


0 comments on commit 7a2a932

Please sign in to comment.