Skip to content

Instantly share code, notes, and snippets.

@tomoki
Created May 16, 2012 00:58
Show Gist options
  • Save tomoki/2706435 to your computer and use it in GitHub Desktop.
Save tomoki/2706435 to your computer and use it in GitHub Desktop.
Hash structure
#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;
}
#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