/* * hash.c, SJ */ #include #include #include #include #include void inithash(struct node *xhash[]){ int i; for(i=0;ir; if(p){ if(p->str){ free(p->str); } free(p); } } xhash[i] = NULL; } } struct node *makenewnode(struct node *xhash[], char *s){ struct node *h; int len; if(s == NULL) return NULL; len = strlen(s); if((h = malloc(sizeof(struct node))) == NULL) return NULL; memset(h, 0, sizeof(struct node)); h->str = malloc(len+2); if(h->str == NULL){ free(h); return NULL; } memset(h->str, 0, len+2); snprintf(h->str, len+1, "%s", s); h->key = DJBHash(s, len); h->r = NULL; return h; } int addnode(struct node *xhash[], char *s){ struct node *p=NULL, *q; unsigned int key = 0; int len; if(s == NULL) return 0; len = strlen(s); key = DJBHash(s, len); if(xhash[hash(key)] == NULL){ xhash[hash(key)] = makenewnode(xhash, s); } else { q = xhash[hash(key)]; while(q != NULL){ p = q; if(p->key == key){ return 0; } else { q = q->r; } } p->r = makenewnode(xhash, s); } return 1; } struct node *findnode(struct node *xhash[], char *s){ struct node *q; unsigned int key; int len; if(s == NULL) return NULL; len = strlen(s); key = DJBHash(s, len); q = xhash[hash(key)]; if(q == NULL) return NULL; while(q != NULL){ if(strcmp(q->str, s) == 0){ return q; } else { q = q->r; } } return NULL; } inline int hash(unsigned int key){ return key % MAXHASH; } unsigned int DJBHash(char* str, unsigned int len){ unsigned int hash = 5381; unsigned int i = 0; for(i=0; i < len; str++, i++){ hash = ((hash << 5) + hash) + (*str); } return hash; }