Created
May 16, 2012 00:58
-
-
Save tomoki/2706435 to your computer and use it in GitHub Desktop.
Hash structure
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 "hash.h" | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
#include <math.h> | |
int hash_func(Hash hash,int key1,int key2); | |
int rehash_func(Hash hash,int gened_key); | |
void expand(Hash hash,size_t new_size); | |
/*Error added checking malloc*/ | |
void *mymalloc(size_t size); | |
typedef enum ENUM_ITEM_FLAG{ | |
FLAG_VALUE = 1, | |
FLAG_EMPTY = -1, | |
FLAG_DELETED = -2, | |
} ITEM_FLAG; | |
typedef struct Item_tag{ | |
int key1; | |
int key2; | |
int value; | |
ITEM_FLAG flag; | |
} Item; | |
struct Hash_tag{ | |
Item *table; | |
int size; | |
int values; | |
}; | |
Hash new_hash(int size){ | |
struct Hash_tag *hash; | |
int i; | |
assert(size > 0); | |
hash = (Hash)mymalloc(sizeof(struct Hash_tag)); | |
hash->size = size; | |
hash->values = 0; | |
hash->table = (Item*)mymalloc(sizeof(Item)*size); | |
for(i=0;i<size;i++){ | |
Item it = {0,0,0,FLAG_EMPTY}; | |
hash->table[i] = it; | |
} | |
return hash; | |
} | |
void display_hash(Hash hash){ | |
int i; | |
printf("-- display hash(%p) --\n",hash); | |
printf("hash's size is %d (%d is filled)\n",hash->size,hash->values); | |
for(i=0;i<hash->size;i++){ | |
printf("hash->table[%d]\t(hash[(%d,%d)]) = (%d,%d)\n", | |
i, | |
hash->table[i].key1, | |
hash->table[i].key2, | |
hash->table[i].value, | |
hash->table[i].flag | |
); | |
} | |
} | |
void delete_hash(Hash hash){ | |
free(hash->table); | |
free(hash); | |
} | |
void add_data(Hash hash,int key1,int key2,int value){ | |
int index; | |
int i; | |
if((hash->values)+1 >= (hash->size)/2){ | |
expand(hash,(hash->size)*2+1); | |
} | |
index = hash_func(hash,key1,key2); | |
for(i=0;i<hash->size;i++){ | |
if((hash->table[index]).flag == FLAG_EMPTY || | |
(hash->table[index]).flag == FLAG_DELETED){ | |
Item it = {key1,key2,value,FLAG_VALUE}; | |
hash->values++; | |
hash->table[index] = it; | |
return; | |
} | |
index = rehash_func(hash,index); | |
} | |
expand(hash,(hash->size)*2+1); | |
add_data(hash,key1,key2,value); | |
} | |
void remove_data(Hash hash,int key1,int key2){ | |
int index; | |
int i; | |
index = hash_func(hash,key1,key2); | |
for(i=0;i<hash->size;i++){ | |
if((hash->table[index]).key1 == key1 && | |
(hash->table[index]).key2 == key2 && | |
(hash->table[index]).flag == FLAG_VALUE){ | |
hash->table[index].flag = FLAG_DELETED; | |
hash->values--; | |
return; | |
} | |
if((hash->table[index]).flag == FLAG_EMPTY){ | |
return; | |
} | |
index = rehash_func(hash,index); | |
} | |
} | |
int search_data(Hash hash,int key1,int key2){ | |
int index; | |
int i; | |
index = hash_func(hash,key1,key2); | |
for(i=0;i<hash->size;i++){ | |
if((hash->table[index]).key1 == key1 && | |
(hash->table[index]).key2 == key2 && | |
(hash->table[index].flag == FLAG_VALUE)){ | |
return (hash->table[index]).value; | |
} | |
if((hash->table[index]).flag == FLAG_EMPTY){ | |
assert(!"(key1,key2) not found!"); | |
return -1; | |
} | |
index = rehash_func(hash,index); | |
} | |
return -1; | |
} | |
bool contain_data(Hash hash,int key1,int key2){ | |
int index; | |
int i; | |
index = hash_func(hash,key1,key2); | |
for(i=0;i<hash->size;i++){ | |
if((hash->table[index]).key1 == key1 && | |
(hash->table[index]).key2 == key2 && | |
(hash->table[index].flag == FLAG_VALUE)){ | |
return true; | |
} | |
if((hash->table[index]).flag == FLAG_EMPTY){ | |
return false; | |
} | |
index = rehash_func(hash,index); | |
} | |
return false; | |
} | |
int hash_func(Hash hash,int key1,int key2){ | |
return ((int)pow((double)key1,(double)key2))%(hash->size); | |
} | |
int rehash_func(Hash hash,int gened_key){ | |
return (gened_key+1)%(hash->size); | |
} | |
void *mymalloc(size_t size){ | |
void *p = malloc(size); | |
if(p == NULL){ | |
fprintf(stderr,"Can't malloc\n"); | |
exit(1); | |
} | |
return p; | |
} | |
void expand(Hash hash,size_t new_size){ | |
assert(new_size >= hash->size); | |
Item *expanded; | |
int i; | |
expanded = realloc(hash->table,(sizeof(Item)*new_size)); | |
if(expanded == NULL){ | |
fprintf(stderr,"Can't realloc\n"); | |
exit(1); | |
} | |
for(i=hash->size;i<new_size;i++){ | |
Item it = {0,0,0,FLAG_EMPTY}; | |
expanded[i] = it; | |
} | |
hash->table = expanded; | |
hash->size = (int)new_size; | |
} |
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 HASH_H_INCLUDED | |
#define HASH_H_INCLUDED | |
#include <stdbool.h> | |
/*This hashmap use (x,y) for key. | |
* and value is int. | |
*/ | |
typedef struct Hash_tag *Hash; | |
Hash new_hash(int size); | |
void delete_hash(Hash hash); | |
void add_data(Hash hash,int key1,int key2,int data); | |
void remove_data(Hash hash,int key1,int key2); | |
bool contain_data(Hash hash,int key1,int key2); | |
int search_data(Hash hash,int key1,int key2); | |
void display_hash(Hash hash); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment