CS 2213 Advanced Programming
Exam 3 Review: Hash Tables Again


Review

One of the problems with the hash table implementations discussed earlier is the limited number of entries that can be put in the table.

One way around this is to use a linked list for all of the entries corresponding to a given hash function value.

The hash table becomes an array of pointers to linked lists.

Consider a hash table "object" with the following hashtable.h file:

typedef struct stringval {
   char *str;
   int val;
} stringval;

/* Return a hash table initialized to empty. */
int hashinit(int size);

/* Insert sval into the hashtable htp.
   Return 1 on success and 0 on failure. */
int hashinsert(stringval sval);

/* Remove sval from the hashtable htp.
   Return 1 on success and 0 on failure. */
int hashremove(stringval sval);

/* Return a pointer to the entry for str in the hashtable htp.
   Return NULL if not found. */
stringval *hashfind(char *str);
Notice that in this description, all implementation issues are hidden from the user.

The implementation we will look at has the hashtable as an array of pointers to linked entries:

typedef struct hashentry {
   stringval sval;
   strcut hashentry *next;
}hashentry;
We can use a modified version of the hash function as before:
static int hashsize;

static int hashfunction(char *str) {
   unsigned int hashval;
   int i;

   hashval = 0;
   for (i=0;str[i]!=0;i++)
      hashval = 37*hashval + str[i];
   return hashval % hashsize;
}
Now we can write the 4 public methods:
int hashinit(int size);
int hashinsert(stringval sval);
int hashremove(stringval sval);
stringval *hashfind(char *str);

Here is the code we wrote in class:

int hashinit(int size){
    hashsize = size;
    htp = (hashentry**)malloc(sizeof(hashentry *)*hashsize);
    int i;
    if (htp == NULL)
        return 0;
    for (i = 0; i < hashsize; i++)
        htp[i] = NULL;
    return 1;
}


int hashinsert(stringval sval) {
    int hashval;
    hashentry* nentry;
    hashval = hashfunction(sval.str);
    if (hashfind(sval.str) != NULL)
        return 0;
    nentry = (hashentry *)malloc(size of(hashentry));
    if (nentry == NULL)
        return 0;
    nentry -> sval = sval;
    nentry -> next = htp[hashval];
    htp[hashval] = nentry;
    return 1;
}
The class ended here.





Practice with doubly linked lists:
typedef struct nodeentry {
   stringval sval;
   struct nodeentry *next;
   struct nodeentry *prev;
} nodeentry;

typedef struct {
   nodeentry *front;
   nodeentry *rear;
} doublelist;

int insert_after(stringval sval, nodeentry *nentryp);
int insert_before(stringval sval, nodeentry *nentryp);
stringval remove(nodeentry *nentryp);