After struggling with this pset for a while I decided to strip it down to its most basic form and try and understand the implementation of hash tables and linked lists by creating my own. To that end I wrote this.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
//PROGRAM MAKES A HASH TABLE CONTAINING LINKED LISTS OF USER INPUTED WORDS
//THIS PROGRAM DOES NOT FREE THE HEAP MEMORY AND SO HAS LEAKS!
//create a node struct
typedef struct node
{
char* data;
struct node *next;
}
node;
//create hash table
node* hashtable[26];
//create pointer to word
char* word = NULL;
//create pointer to node
node* new_node = NULL;
int main(void)
{
//initialize hash table (make all positions = NULL)
for (int i = 0; i < 26; i++)
{
hashtable[i] = NULL;
}
//user input a number to determine how many items in the hash table
int listees;
printf("How many nodes do you want to create?: ");
scanf("%i", &listees);
//make nodes
for( int i = 0; i < listees; i++)
{
//user input a word to go into the node's data field
word = malloc(sizeof(word));
printf("Type a word: ");
scanf("%s", word);
//create node containing the inputed word
//allocate memory for a new node
new_node = malloc(sizeof(node)); //creates a pointer to a node called 'new_node' that points to a node sized chunk of memory
//check to see if there is enough memory to create a node
if (new_node == NULL)
{
return 1;
fprintf(stderr, "not enough memory to malloc a node\n");
}
//place the word into the nodes data field
new_node->data = word;
//set the pointer in the 'next' field to point to NULL
new_node->next = NULL;
//hash the inputed word
int hashval = tolower(word[0]) - 'a';//first letter in the word is given a number 0 - 25.
//the new nodes next pointer points to the same thing that the pointer at hashtable[hashval] points to
//i.e. the node in that position or NULL if there is no node there
new_node->next = hashtable[hashval];
//point the pointer in hashtable[hashval] at the new node, making it the node at the top of the list
hashtable[hashval] = new_node;
}
//print out items placed in hash table
for( int j = 0; j < 26; j++)
{
if(hashtable[j] != NULL)
{
node* cursor = hashtable[j];
printf("words at hashtable[%i] are: ", j);
while(cursor != NULL)
{
printf("%s ", cursor->data);
cursor = cursor->next;
}
printf("\n");
}
}
//NEED TO FREE MEMORY!
}
This seems to work. Entering the words: apple, orange, pear, peach. gives me the result:
How many nodes do you want to create?: 4
Type a word: apple
Type a word: orange
Type a word: pear
Type a word: peach
words at hashtable[0] are: apple
words at hashtable[14] are: orange
words at hashtable[15] are: peach pear
I then noticed that the problem set uses an array of chars to store the words loaded instead of dynamically allocating memory. When I attempt the same, replacing
//create pointer to word
char* word = NULL;
with
//create array to hold word
char word[46];
and remove: word = malloc(sizeof(word)); I get the result:
How many nodes do you want to create?: 4
Type a word: apple
Type a word: orange
Type a word: pear
Type a word: peach
words at hashtable[0] are: peach
words at hashtable[14] are: peach
words at hashtable[15] are: peach peach
All of the words are replaced with the last word entered.
Can anyone help? I assume I'm making a mistake with what I'm pointing to(?). I'm obviously missing something very simple. I think I've gone mad. Many thanks.