forked from kennedyufersa/hashTable
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHash.cpp
More file actions
239 lines (220 loc) · 7.66 KB
/
Hash.cpp
File metadata and controls
239 lines (220 loc) · 7.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#ifndef HASH_CPP
#define HASH_CPP
#include "cidade.cpp" // Chamada da função que contém as estuturas salvas
#include <math.h> // Biblioteca para operações matemáticas
#include <stdio.h> // Entrada e Saída de Hs
#include <stdlib.h> // Emulador do prompt do sistema
/**
* 3/4 do espaço será utilizado para a tabela Hash
* Os 1/4 restantes do espaço serão empregados para o tratamento de colisão
*/
#define SIZE 16
/**
* Criação de um vetor de ponteiros chamado 'hash' do tipo dataItem
* Essa variável será a própria Tabela Hash
*/
typedef dataItem *hash[SIZE];
// Funções
void init(hash &H);
int inserir(hash H, dataItem *d, int (*funcHash)(dataItem *));
int buscar(hash H, int chave, int (*funcHash)(dataItem *));
int remover(hash H, int chave, int (*funcHash)(dataItem *));
int divisao(dataItem *d);
void printHash(hash H);
void printItem(hash H, int key);
void saveData(hash H);
/**
* Função que inicia a Tabela Hash
* Ela percorre todos os espaços vagos limpando-os
*/
void init(hash &H) {
for (int i = 0; i < SIZE; i++) {
H[i] = 0;
}
}
/**
* Insere elementos na tabela Hash
* @param H
* @param d
* @param funcHash
* @return int
*/
int inserir(hash H, dataItem *d, int (*funcHash)(dataItem *)) {
// Variável inteira que irá receber o resultado da função Hash
int key = funcHash(d);
// Se a estrutura estiver vazia, a cópia do item será guardada nela
if (H[key] == 0 || H[key]->key == -1) {
// Cópia do item que será inserido
dataItem *copy = (dataItem*)malloc(sizeof(dataItem));
*copy = *d;
H[key] = copy;
return 0; // Retorna 0 se der certo
}
/**
* Tratamento de Colisão Encadeado Interior
* Ele basicamente usa uma parte da tabela como um vetor normal para alocar estruturas que tenham colidido
*/
for(int i = ((SIZE/4) * 3); i < SIZE; i++){
if(H[i] == 0 || H[i]->key == -1){
// Cópia do item que será inserido
dataItem *copy = (dataItem*)malloc(sizeof(dataItem));
*copy = *d;
H[i] = copy;
return 0; // Retorna 0 se der certo
}
}
return -1; // Retorna -1 se der errado
}
/**
* Função que busca um elemento em uma posição da Tabela
* @param H
* @param key
* @param funcHash
* @return dataItem*
*/
int buscar(hash H, int chave, int (*funcHash)(dataItem *)){
// Checa se a chave do item está dentro dos critérios de busca
if (chave <= 0) {
printf("Chave Inválida para busca/n");
return(-1);
}
// Cria um item com a mesma chave pesquisada
dataItem *d = (dataItem*)malloc(sizeof(dataItem));
d->key = chave;
int key = funcHash(d);
// Se a chave buscada estiver na possisão key, retorna a posição key
if (H[key]->key == d->key) {
free(d);
return key;
}
// Se a key for -1 ela irá buscar na segunda parte da tabela
else if (H[key] != 0) {
for (int i = ((SIZE/4) * 3); i < SIZE; i++){
// Se chegar a uma posição vazia antes de achar, retorna -1 (erro)
if (H[i] == 0){
printf("\nItem não encontrado\n");
free(d);
return -1;
}
// Se achar a key em alguma das posições, retorna a posição i
else if (H[i]->key == d->key){
free(d);
return i;
}
}
}
// Em caso de erro
printf("\nItem não encontrado\n");
free(d);
return -1;
}
/**
* Função que Remove um Elemento da Tabela
* @param H
* @param d
* @param funcHash
* @return int
*/
int remover(hash H, int chave, int (*funcHash)(dataItem *)) {
int key = buscar(H, chave, funcHash); // Busco a posição do item na tabela
if(key == -1){
return -1;
}
// Apago o item de acordo com a posição
dataItem *purge = H[key]; // Purge vai receber a chave do item, e limpar o local
// delete purge; //linux
free(purge); // windows e linux
H[key] = (dataItem*) malloc(sizeof(dataItem));
H[key]->key = -1; // O item apagado ganha a chave -1, para indicar que algum item já esteve ali
return 0; // Retorna 0 se der tudo certo
}
/**
* Função Hash da Divisão
* @param d
* @return int
*/
int divisao(dataItem *d) {
// O corpo principal da tabela será até a posição 255, o restante será para tratamento
return d->key % ((SIZE/4) * 3);
}
/**
* Função que imprime a tabela Hash
* @param H
*/
void printHash(hash H){
printf("\n ==== CORPO PRINCIPAL DA TABELA HASH ==== \n\n\n");
for (int i = 0; i < ((SIZE/4) * 3); i++) {
if(H[i] == 0){
printf(" %d -> ==== SLOT VAZIO ====\n\n", i); // Caso o slot esteja vazio
}
else if(H[i]->key == -1){
printf(" %d -> ==== SLOT APAGADO ====\n\n", i); // Caso o slot tenha sido apagado
}
else{
printf(" %d -> = %d =\n Cidade : %s Estado: %s\n Latitude: %.2f\n Longitude %.2f\n\n", i, H[i]->key, H[i]->city.cidade, H[i]->city.estado, H[i]->GPS.la, H[i]->GPS.lo);
}
}
printf("\n\n ==== TRATAMENTO DE COLISAO ====\n\n\n");
for (int i = ((SIZE/4) * 3); i < SIZE; i++) {
if(H[i] == 0){
printf(" %d -> ==== SLOT VAZIO ====\n\n", i); // Caso o slot esteja vazio
}
else if(H[i]->key == -1){
printf(" %d -> ==== SLOT APAGADO ====\n\n", i); // Caso o slot tenha sido apagado
}
else{
printf(" %d -> = %d =\n Cidade : %s Estado: %s\n Latitude: %.2f\n Longitude %.2f\n\n", i, H[i]->key, H[i]->city.cidade, H[i]->city.estado, H[i]->GPS.la, H[i]->GPS.lo);
}
}
}
/**
* Função que recebe a tabela e a posição de um item e imprime o item
* @param H
* @param key
*/
void printItem(hash H, int key){
if(H[key] == 0){
printf(" %d -> ==== SLOT VAZIO ====\n\n", key); // Caso o slot esteja vazio
}
else if(H[key]->key == -1){
printf(" %d -> ==== SLOT APAGADO ====\n\n", key); // Caso o slot tenha sido apagado
}
else{
printf(" %d -> = %d =\n Cidade : %s Estado: %s\n Latitude: %.2f\n Longitude %.2f\n\n", key, H[key]->key, H[key]->city.cidade, H[key]->city.estado, H[key]->GPS.la, H[key]->GPS.lo);
}
}
/**
* Função salva a tabela Hash em um arquivo
* @param H
*/
void saveData(hash H){
FILE *File_Hash;
File_Hash = fopen("Tabela_hash_Ordenada.txt","w");
fprintf(File_Hash," ==== CORPO PRINCIPAL DA TABELA HASH ==== \n\n\n");
for (int i = 0; i < ((SIZE/4) * 3); i++) {
if(H[i] == 0){
fprintf(File_Hash," %d -> ==== SLOT VAZIO ====\n\n", i);
}
else if(H[i]->key == -1){
fprintf(File_Hash," %d -> ==== SLOT APAGADO ====\n\n", i);
}
else{
fprintf(File_Hash," %d -> = %d =\n Cidade : %s Estado: %s\n Latitude: %.2f\n Longitude %.2f\n\n", i, H[i]->key, H[i]->city.cidade, H[i]->city.estado, H[i]->GPS.la, H[i]->GPS.lo);
}
}
fprintf(File_Hash,"\n ==== TRATAMENTO DE COLISAO ====\n\n\n");
for (int i = ((SIZE/4) * 3); i < SIZE; i++) {
if(H[i] == 0){
fprintf(File_Hash," %d -> ==== SLOT VAZIO ====\n\n", i);
}
else if(H[i]->key == -1){
fprintf(File_Hash," %d -> ==== SLOT APAGADO ====\n\n", i);
}
else{
fprintf(File_Hash," %d -> = %d =\n Cidade : %s Estado: %s\n Latitude: %.2f\n Longitude %.2f\n\n", i, H[i]->key, H[i]->city.cidade, H[i]->city.estado, H[i]->GPS.la, H[i]->GPS.lo);
}
}
fprintf(File_Hash, "\n ==========================================\n");
fclose(File_Hash);
}
#endif