codice:
#include <stdio.h>
#include <stdlib.h>
#define M 4093
#define DIM_ELEM 89
typedef struct tagNodo
{
int key;
char* val;
struct tagNodo* next;
} nodo;
typedef struct tagHashMap
{
nodo* lista[M];
}hashmap;
typedef int (*HashFunz)(int k);//puntatore a funzione
int hash1(int k);
void hm_free_list(nodo* first);
void hm_insert(hashmap* h, char* e, int k, HashFunz hf);
nodo* hm_delete_node(nodo *first, int k);
void hm_delete(hashmap* h, int k, HashFunz hf);
char* hm_search(hashmap* h, int k, HashFunz hf);
void print(hashmap* h);
int menu();
int main()
{
hashmap tavola;
int metodo;
HashFunz funzHash;
int chiave;
int scelta;
char* elemento;
int k;
funzHash = hash1;
for (k = 0; k < M; k++)
tavola.lista[k] = NULL;
while(1)
{
scelta = menu();
elemento = (char*)malloc(DIM_ELEM * sizeof(char) + 1);
if ( !elemento )
{
printf("Memoria insufficiente.\n");
break;
}
switch (scelta)
{
case 1:
printf("Inserisci chiave:\n");
scanf("%d", &chiave);
printf("Inserisci elemento:\n");
scanf("%s", elemento);
hm_insert(&tavola,elemento,chiave,funzHash);
break;
case 2:
printf("Cerca chiave:\n");
scanf("%d", &chiave);
elemento = hm_search(&tavola,chiave,funzHash);
if(elemento==NULL)
printf("Chiave non trovata.\n");
else
printf("Elemento trovato: %s\n", elemento);
break;
case 3:
printf("Cancella chiave:\n");
scanf("%d", &chiave);
hm_delete(&tavola,chiave,funzHash);
break;
case 4:
print(&tavola);
break;
default:
for (k = 0; k < M; k++)
hm_free_list(tavola.lista[k]);
return 0;
}
}
return 0;
}
int hash1(int k)
{
return k%M;
}
void hm_free_list(nodo* first)
{
nodo *n1 = first, *n2;
while ( n1 != NULL )
{
free(n1->val);
n2 = n1->next;
free(n1);
n1 = n2;
}
}
void hm_insert(hashmap* h, char* e, int k, HashFunz hf)
{
nodo *temp, *nuovo;
int indice;
if ( hm_search(h, k, hf) != NULL )
{
printf("La chiave inserita, %d, e' gia' presente nel dizionario.\n", k);
return;
}
indice = (*hf)(k);
nuovo = (nodo*)malloc(sizeof(nodo));
if ( !nuovo )
{
printf("Memoria insufficiente.\n");
return;
}
nuovo->key = k;
nuovo->val = e;
nuovo->next = NULL;
temp = h->lista[indice];
if(temp != NULL)
{
while(temp->next != NULL)
{
temp = temp->next;
}
temp->next = nuovo;
}
else
{
h->lista[indice] = nuovo;
}
printf("Voce inserita nel dizionario.\n");
}
nodo* hm_delete_node(nodo *first, int k)
{
nodo *n1 = first, *n2;
nodo *prev = NULL;
if ( first == NULL )
return NULL;
while ( n1 != NULL )
{
if ( n1->key == k )
{
if ( !prev ) /* Se prev è NULL, stiamo cancellando il primo nodo della lista */
{
n1 = n1->next;
free(first);
return n1;
}
else
{
n2 = n1->next;
free(n1);
prev->next = n2;
return first;
}
}
else
{
prev = n1;
n1 = n1->next;
}
}
return first;
}
void hm_delete(hashmap* h, int k, HashFunz hf)
{
int indice = (*hf)(k);
nodo* temp = h->lista[indice];
h->lista[indice] = hm_delete_node(temp, k);
}
char* hm_search(hashmap* h, int k, HashFunz hf)
{
int indice = (*hf)(k);
nodo* temp = h->lista[indice];
while(temp != NULL)
{
if(temp->key == k)
{
return temp->val;
}
else
{
temp = temp->next;
}
}
return NULL;
}
void print(hashmap* h)
{
int i;
nodo* temp;
printf("\n\n********************************\n");
printf("Voci dizionario:\n");
printf("Indice\t\tChiave\t\tElemento\n");
for(i = 0; i < M; i++)
{
temp = h->lista[i];
while(temp != NULL)
{
printf("%d\t\t%d\t\t%s\n",i,temp->key,temp->val);
temp = temp->next;
}
}
printf("\n********************************\n\n");
return;
}
int menu()
{
int scelta;
printf("\nMENU' DIZIONARIO");
printf("\n1) Aggiungi voce (con chiavi distinte)");
printf("\n2) Cerca chiave");
printf("\n3) Elimina chiave");
printf("\n4) Visualizza dizionario");
printf("\n5) Esci");
printf("\nScelta: ");
scanf("%d", &scelta);
return scelta;
}