Skip to content

Instantly share code, notes, and snippets.

@cristipufu
Created March 2, 2017 17:50
Show Gist options
  • Save cristipufu/731741a3f29c42662ed8bef4f03c01b8 to your computer and use it in GitHub Desktop.
Save cristipufu/731741a3f29c42662ed8bef4f03c01b8 to your computer and use it in GitHub Desktop.
Hashtable implementation
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utils.h"
#include "hash.h"
#include "hashtable.h"
#define DEBUG 0
hashtable *create_hashtable(int length)
{
int i;
hashtable *hash = malloc(sizeof(hashtable));
DIE(hash == NULL, "malloc hashtable");
hash->length = length;
hash->first = malloc(sizeof(node *) * length);
DIE(hash->first == NULL, "malloc hashtable first");
for (i = 0; i < length; i++)
hash->first[i] = NULL;
if (DEBUG)
printf("Create hashtable");
return hash;
}
node *create_node(char *word)
{
int length = strlen(word) + 1;
node *new = malloc(sizeof(node));
DIE(new == NULL, "malloc insert node");
new->val = malloc(sizeof(char) * length);
DIE(new->val == NULL, "malloc insert node value");
memcpy(new->val, word, length);
if (DEBUG)
printf("Create hashtable node");
return new;
}
void add(hashtable *h, char *word)
{
int index;
node *first;
node *new;
new = find(h, word);
if (new == NULL) {
index = hash(word, h->length);
new = create_node(word);
first = h->first[index];
if (first == NULL) {
h->first[index] = new;
h->first[index]->next = NULL;
} else {
new->next = NULL;
while (first->next != NULL)
first = first->next;
first->next = new;
}
}
}
node *find(hashtable *h, char *word)
{
int index = hash(word, h->length);
node *n = h->first[index];
while (n != NULL) {
if (strcmp(n->val, word) == 0)
return n;
n = n->next;
}
return n;
}
void print_bucket(hashtable *h, int index, FILE *f)
{
node *first = NULL;
DIE(index >= h->length, "Index out of bounds");
first = h->first[index];
if (first != NULL) {
while (first != NULL) {
fprintf(f, "%s ", first->val);
first = first->next;
}
fprintf(f, "\n");
}
}
void print_hashtable(hashtable *h, FILE *f)
{
int i = 0;
for (i = 0; i < h->length; i++)
print_bucket(h, i, f);
}
int remove_word(hashtable *h, char *word)
{
int index;
node *first;
node *n;
n = find(h, word);
if (n == NULL)
return -1;
index = hash(word, h->length);
if (n == h->first[index]) {
h->first[index] = h->first[index]->next;
free_node(n);
return 0;
}
first = h->first[index];
while (first->next != n && first->next != NULL)
first = first->next;
if (first->next != NULL) {
first->next = n->next;
free_node(n);
}
return -1;
}
void free_node(node *n)
{
free(n->val);
free(n);
}
void free_hashtable(hashtable *h)
{
clear(h);
free(h->first);
free(h);
}
void clear(hashtable *h)
{
int i;
node *n;
node *temp;
for (i = 0; i < h->length; i++) {
n = h->first[i];
while (n != NULL) {
temp = n;
n = n->next;
free_node(temp);
}
h->first[i] = NULL;
}
}
void resize(hashtable *h, int length)
{
int i;
node *n;
hashtable *h_aux = create_hashtable(length);
hashtable swap;
for (i = 0; i < h->length; i++)
for (n = h->first[i]; n != NULL; n = n->next)
add(h_aux, n->val);
swap = *h;
*h = *h_aux;
*h_aux = swap;
free_hashtable(h_aux);
}
#ifndef _HASHTABLE_H
#define _HASHTABLE_H
typedef struct node {
char *val;
struct node *next;
} node;
typedef struct hashtable {
node **first;
int length;
} hashtable;
hashtable *create_hashtable(int length);
node *create_node(char *word);
void add(hashtable *h, char *word);
node *find(hashtable *h, char *word);
void print_bucket(hashtable *h, int index, FILE *f);
void print_bucket_by_node(node *first, FILE *f);
void print_hashtable(hashtable *h, FILE *f);
int remove_word(hashtable *h, char *word);
void resize(hashtable *h, int length);
void clear(hashtable *h);
void free_hashtable(hashtable *h);
void free_node(node *n);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment