mirror of
https://github.com/dvorka/hstr.git
synced 2024-12-25 08:55:09 +08:00
Adding hash map and radix sort.
This commit is contained in:
parent
273c8456e2
commit
6b8d1564bc
4 changed files with 224 additions and 0 deletions
67
src/hashmap.c
Normal file
67
src/hashmap.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "include/hashmap.h"
|
||||||
|
|
||||||
|
unsigned int hashmap_hash( const char *str ) {
|
||||||
|
int i;
|
||||||
|
unsigned int result = 0;
|
||||||
|
|
||||||
|
for( i = 0; str[ i ] != '\0'; i++ )
|
||||||
|
result = result * 31 + str[ i ];
|
||||||
|
|
||||||
|
return result % HASH_MAP_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hashmap_init( HashMap * hs ) {
|
||||||
|
int i;
|
||||||
|
hs->currentSize = 0;
|
||||||
|
for( i = 0; i < HASH_MAP_SIZE; i++ ) {
|
||||||
|
hs->lists[ i ] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *hashmap_get( const HashMap * hs, const char *key ) {
|
||||||
|
int listNum = hashmap_hash( key );
|
||||||
|
struct HashMapNode *ptr = hs->lists[ listNum ];
|
||||||
|
|
||||||
|
while( ptr != NULL && strcmp( ptr->key, key ) != 0 )
|
||||||
|
ptr = ptr->next;
|
||||||
|
|
||||||
|
return (ptr != NULL? ptr->value : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hashmap_put( HashMap * hs, const char *key, void *value) {
|
||||||
|
struct HashMapNode *newNode;
|
||||||
|
int listNum;
|
||||||
|
|
||||||
|
if( hashmap_get( hs, key ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
listNum = hashmap_hash( key );
|
||||||
|
|
||||||
|
|
||||||
|
newNode = (struct HashMapNode *) malloc( sizeof ( struct HashMapNode ) );
|
||||||
|
if( newNode == NULL ) {
|
||||||
|
fprintf( stderr, "Error allocating node" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
newNode->key = strdup( key );
|
||||||
|
newNode->value = value;
|
||||||
|
newNode->next = hs->lists[ listNum ];
|
||||||
|
hs->lists[ listNum ] = newNode;
|
||||||
|
hs->currentSize++;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hashmap_size(const HashMap * hs) {
|
||||||
|
return hs->currentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hashmap_print( const HashMap * hs ) {
|
||||||
|
int i;
|
||||||
|
struct HashMapNode *ptr;
|
||||||
|
|
||||||
|
for( i = 0; i < HASH_MAP_SIZE; i++ )
|
||||||
|
for( ptr = hs->lists[ i ]; ptr != NULL; ptr = ptr->next )
|
||||||
|
printf( "%s\n", ptr->key );
|
||||||
|
}
|
27
src/include/hashmap.h
Normal file
27
src/include/hashmap.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef _HASHMAP_H_
|
||||||
|
#define _HASHMAP_H_
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define HASH_MAP_SIZE 10007
|
||||||
|
|
||||||
|
struct HashMapNode {
|
||||||
|
char *key;
|
||||||
|
void *value;
|
||||||
|
struct HashMapNode *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct HashMapNode * lists[HASH_MAP_SIZE];
|
||||||
|
int currentSize;
|
||||||
|
} HashMap;
|
||||||
|
|
||||||
|
void hashmap_init( HashMap *hm );
|
||||||
|
void *hashmap_get( const HashMap *hm, const char *key );
|
||||||
|
int hashmap_put( HashMap *hm, const char *key, void *value );
|
||||||
|
int hashmap_size( const HashMap *hm );
|
||||||
|
void hashmap_print( const HashMap *hm );
|
||||||
|
|
||||||
|
#endif /* HASHMAP_H_ */
|
23
src/include/radixsort.h
Normal file
23
src/include/radixsort.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef RADIXSORT_H_
|
||||||
|
#define RADIXSORT_H_
|
||||||
|
|
||||||
|
typedef struct radixitem {
|
||||||
|
unsigned key;
|
||||||
|
void *data;
|
||||||
|
struct radixitem *next;
|
||||||
|
} RadixItem;
|
||||||
|
|
||||||
|
#define SIX2FOUR_SIZE 1000
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned size;
|
||||||
|
unsigned maxValue;
|
||||||
|
RadixItem **six2four[SIX2FOUR_SIZE];
|
||||||
|
} RadixSorter;
|
||||||
|
|
||||||
|
void radixsort_init(RadixSorter *rs);
|
||||||
|
void radixsort_add(RadixSorter *rs, RadixItem *item);
|
||||||
|
RadixItem *radix_cut(RadixSorter *rs, unsigned key, void *data);
|
||||||
|
RadixItem **radixsort_dump(RadixSorter *rs);
|
||||||
|
|
||||||
|
#endif /* RADIXSORT_H_ */
|
107
src/radixsort.c
Normal file
107
src/radixsort.c
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
#include "include/radixsort.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
RadixItem **radixsort_get_slot() {
|
||||||
|
RadixItem **slot=malloc(SIX2FOUR_SIZE * sizeof(RadixItem*));
|
||||||
|
memset(slot, 0, SIX2FOUR_SIZE * sizeof(RadixItem*));
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void radixsort_init(RadixSorter *rs) {
|
||||||
|
rs->size=0;
|
||||||
|
memset(rs->six2four, 0, SIX2FOUR_SIZE * sizeof(RadixItem*));
|
||||||
|
rs->maxValue=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void radixsort_add(RadixSorter *rs, RadixItem *item) {
|
||||||
|
double d = ((double) item->key)/1000.0;
|
||||||
|
unsigned six2four = (unsigned)trunc(d);
|
||||||
|
unsigned three2zero=item->key-six2four*1000;
|
||||||
|
|
||||||
|
if(rs->six2four[six2four]==NULL) {
|
||||||
|
rs->six2four[six2four]=radixsort_get_slot();
|
||||||
|
}
|
||||||
|
|
||||||
|
RadixItem *chain=rs->six2four[six2four][three2zero];
|
||||||
|
rs->six2four[six2four][three2zero]=item;
|
||||||
|
if(chain==NULL) {
|
||||||
|
item->next=NULL;
|
||||||
|
} else {
|
||||||
|
item->next=chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs->size++;
|
||||||
|
rs->maxValue=(rs->maxValue>item->key?rs->maxValue:item->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
RadixItem **radixsort_dump(RadixSorter *rs) {
|
||||||
|
if(rs->size>0) {
|
||||||
|
RadixItem **result=malloc(rs->size * sizeof(RadixItem *));
|
||||||
|
double d = ((double)rs->maxValue)/1000.0;
|
||||||
|
int six2four = (int)trunc(d);
|
||||||
|
|
||||||
|
int s, t, i=0;
|
||||||
|
s=six2four;
|
||||||
|
do {
|
||||||
|
t=SIX2FOUR_SIZE-1;
|
||||||
|
do {
|
||||||
|
if(rs->six2four[s]!=NULL) {
|
||||||
|
if(rs->six2four[s][t]!=NULL) {
|
||||||
|
result[i++]=rs->six2four[s][t];
|
||||||
|
|
||||||
|
RadixItem *ri=rs->six2four[s][t]->next;
|
||||||
|
while(ri) {
|
||||||
|
result[i++]=ri;
|
||||||
|
ri=ri->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(--t>=0);
|
||||||
|
} while(--s>=0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RadixItem *radix_cut(RadixSorter *rs, unsigned key, void *data) {
|
||||||
|
if(key<=rs->maxValue) {
|
||||||
|
double d = ((double) key)/1000.0;
|
||||||
|
unsigned six2four = (unsigned)trunc(d);
|
||||||
|
unsigned three2zero=key-six2four*1000;
|
||||||
|
|
||||||
|
if(rs->six2four[six2four]) {
|
||||||
|
RadixItem *ri=rs->six2four[six2four][three2zero];
|
||||||
|
RadixItem *lastRi=NULL;
|
||||||
|
while(ri->data!=data) {
|
||||||
|
if(ri->next) {
|
||||||
|
lastRi=ri;
|
||||||
|
ri=ri->next;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ri->data==data) {
|
||||||
|
if(lastRi) {
|
||||||
|
lastRi->next=ri->next;
|
||||||
|
} else {
|
||||||
|
rs->six2four[six2four][three2zero]=ri->next;
|
||||||
|
}
|
||||||
|
ri->next=NULL;
|
||||||
|
rs->size--;
|
||||||
|
return ri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void radixsort_destroy(RadixSorter *rs) {
|
||||||
|
// TODO destroy RadixItems chains
|
||||||
|
// TODO destroy three2one segments
|
||||||
|
// TODO destroy six2four
|
||||||
|
}
|
Loading…
Reference in a new issue