Created
March 2, 2017 17:50
-
-
Save cristipufu/731741a3f29c42662ed8bef4f03c01b8 to your computer and use it in GitHub Desktop.
Hashtable implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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