Reputation: 67
I'm trying to create a hash table program, that can input a hash key and a string data that will be stored in the hash table. Everything is fine except in "Menu == 2", everytime I try to search a string data by inputting its hash key, one (the last positioned) hash key in the table is changed to what I had inputted in "Menu == 2".
Here's the hash table from "Menu == 4" with viewAll ()
function (after I input hash keys, and string datas through "Menu == 1"):
//FORMAT:
//[index]: [key] (string data) -> [key] (string data) -> ..
--------------------------------------------------------------------------------
//after I finished inputting all hash keys and string datas through menu 1
[0]: 0 (INDIA) -> 97 (PAKISTAN) -> 194 (BURMA) -> 291 (AFGHANISTAN)
[1]: 1 (UNITED STATES) -> 98 (CANADA) -> 195 (MEXICO) -> 292 (PANAMA)
[2]: 2 (THE NETHERLANDS) -> 99 (LUXEMBOURG) -> 196 (BELGIUM) -> 293 (FRANCE)
[3]: 3 (SYRIA) -> 100 (LEBANON) -> 197 (ISRAEL) -> 294 (BAHRAIN)
//this hash table is correct
--------------------------------------------------------------------------------
after menu 2 (last key inputted on menu 2 was 0)
[0]: 0 (INDIA) -> 97 (PAKISTAN) -> 194 (BURMA) -> 291 (AFGHANISTAN)
[1]: 1 (UNITED STATES) -> 98 (CANADA) -> 195 (MEXICO) -> 292 (PANAMA)
[2]: 2 (THE NETHERLANDS) -> 99 (LUXEMBOURG) -> 196 (BELGIUM) -> 293 (FRANCE)
[3]: 3 (SYRIA) -> 100 (LEBANON) -> 197 (ISRAEL) -> 0 (BAHRAIN)
//(why is BAHRAIN key 0, it should be 294)
--------------------------------------------------------------------------------
after menu 2 (last key inputted on menu 2 was 99)
[0]: 0 (INDIA) -> 97 (PAKISTAN) -> 194 (BURMA) -> 291 (AFGHANISTAN)
[1]: 1 (UNITED STATES) -> 98 (CANADA) -> 195 (MEXICO) -> 292 (PANAMA)
[2]: 2 (THE NETHERLANDS) -> 99 (LUXEMBOURG) -> 196 (BELGIUM) -> 293 (FRANCE)
[3]: 3 (SYRIA) -> 100 (LEBANON) -> 197 (ISRAEL) -> 99 (BAHRAIN)
//(why is BAHRAIN key 99, it should be 294)
As you can see, it's always the last positioned one to be changed by input menu 2.
Below is the source code, to not waste your time, I would look at the void viewStrData ()
function.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct data {
int key;
char strData [100];
struct data *next;
}*head [97], *tail [97], *node, *curr;
//index location within hash table = key % 97
int hashing (int key) {
int result = key % 97;
return result;
}
//input key and strData, push it to hash table
void push (int key, char strData [100]) {
node = (struct data*) malloc(sizeof(struct data));
node->key = key;
strcpy (node->strData, strData);
node->next = NULL;
int idx = hashing (key);
if (!head [idx]) {
head [idx] = tail [idx] = node;
} else {
tail [idx]->next = node;
tail [idx] = node;
}
}
//see strData based on key
void viewStrData (int key) {
curr = head [hashing (key)];
node->key = key;
while (true) {
if (curr->key == node->key) {
printf ("[%s]\n", curr->strData);
break;
} else {
curr = curr->next;
}
}
}
//print out current hash table
void viewAll () {
for (int i = 0; i < 97; i++) {
printf ("[%d]: ", i);
if (!head [i]) {
printf ("-\n");
} else {
curr = head [i];
while (curr) {
if (curr == head [i]) {
printf ("%d", curr->key);
printf (" (%s)", curr->strData);
} else {
printf (" -> %d", curr->key);
printf (" (%s)", curr->strData);
}
curr = curr->next;
}
printf ("\n");
}
}
}
int main () {
int menu, key;
char strData [100];
while (true) {
printf ("=======================================\n");
printf ("MENU [1-3]: \n");
printf ("1. INPUT DATA\n");
printf ("2. SEARCH DATA\n");
printf ("3. EXIT\n");
printf ("=======================================\n");
scanf ("%d", &menu);
if (menu == 1) {
printf ("ENTER KEY AND STRING DATA: \n");
scanf ("%d %[^\n]", &key, strData);
push (key, strData);
printf ("HASH TABLE UPDATED!\n");
} else if (menu == 2) {
printf ("ENTER KEY TO FIND STRING DATA: \n");
scanf ("%d", &key);
printf ("STRING DATA OF KEY [%d] IS: ", key);
viewStrData (key);
} else if (menu == 3) {
printf ("PROGRAM EXITED\n");
break;
} else if (menu = 4) {
viewAll ();
}
}
return 0;
}
Is there any way I could fix this? And sorry in advance that my code is sloppy and horrible to read.
Upvotes: 0
Views: 40
Reputation: 185
It happens because every time you call push you allocate new memory and store pointer to that memory in node:
node = (struct data*) malloc(sizeof(struct data));
After that, this allocated data is inserted into the table, but the node still points to that data. And then when you run viewStrData you do node->key = key, and the node at this moment still points to the data that was last inserted when you called push. That's why every time you call viewStrData, last inserted node's key is updated to the received key.
I'd suggest to compare received key directly, like this:
void viewStrData (int key) {
curr = head [hashing (key)];
// node->key = key; <-- No need for this
while (true) {
if (curr->key == key) { // <-- compare key directly, instead of storing it into node->key
printf ("[%s]\n", curr->strData);
break;
} else {
curr = curr->next;
}
}
P.S. There's a typo on this line:
} else if (menu = 4) {
it should be == instead of =. Currently if menu is not 1, 2 or 3, it will assign 4 to it inside that if statement, and the result of 4 will be true every time. So even if you enter 7 there, menu will be overwritten by 4 and viewAll will be called.
Upvotes: 2