Beruflich Dokumente
Kultur Dokumente
Una tabla hash, mapa hash, tabla de dispersin o tabla fragmentada es una estructura de
datos que asocia llaves o claves con valores. La operacin principal que soporta de manera
eficiente es la bsqueda: permite el acceso a los elementos (telfono y direccin, por ejemplo)
almacenados a partir de una clave generada (usando el nombre o nmero de cuenta, por
ejemplo). Funciona transformando la clave con una funcin hash en un hash, un nmero que
identifica la posicin (casilla o cubeta) donde la tabla hash localiza el valor deseado.
Un ejemplo prctico para ilustrar que es una tabla hash es el siguiente: Se necesita organizar
los peridicos que llegan diariamente de tal forma que se puedan ubicar de forma rpida,
entonces se hace de la siguiente forma - se hace una gran caja para guardar todos los
peridicos (una tabla), y se divide en 31 contenedores (ahora es una "hash table" o tabla
fragmentada), y la clave para guardar los peridicos es el da de publicacin (ndice). Cuando
se requiere buscar un peridico se busca por el da que fue publicado y as se sabe en que
zcalo (bucket) est. Varios peridicos quedarn guardados en el mismo zcalo (es decir
colisionan al ser almacenados), lo que implica buscar en la sub-lista que se guarda en cada
zcalo. De esta forma se reduce el tamao de las bsquedas de O(n) a, en el mejor de los
casos, O(1) y, en el peor, a O(log(n)).
Las tablas hash se suelen implementar sobre vectores de una dimensin, aunque se pueden
hacer implementaciones multi-dimensionales basadas en varias claves. Como en el caso de
los arrays, las tablas hash proveen tiempo constante de bsqueda promedio O(1),1 sin
importar el nmero de elementos en la tabla. Sin embargo, en casos particularmente malos el
tiempo de bsqueda puede llegar a O(n), es decir, en funcin del nmero de elementos.
Comparada con otras estructuras de arrays asociadas, las tablas hash son ms tiles cuando
se almacenan grandes cantidades de informacin.
Las tablas hash almacenan la informacin en posiciones pseudo-aleatorias, as que el acceso
ordenado a su contenido es bastante lento. Otras estructuras como rboles binarios autobalanceables tienen un tiempo promedio de bsqueda mayor (tiempo de bsqueda O(log n)),
pero la informacin est ordenada en todo momento.
#include<stdio.h>
1. #include<stdlib.h>
2.
3. #define MAXC 10//MAXIMO TAMAO DE UNA CADENA
4. #define MAXA 10//TAMAO DE LA TABLA
5.
6. struct nodo
7. {
8.
char *cadena;
9.
10.
};
11.
12.
13.
14.
15.
16.
while((ascii=cadenaux[i++])!='')
17.
clave+=ascii;
18.
19.
20.
return clave;
}
21.
22.
23.
int posicion=clave%MAXA;
24.
25.
26.
return posicion;
}
27.
28.
29.
30.
31.
32.
33.
34.
35.
if (*ptabla==NULL)
36.
37.
38.
39.
else
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
printf("NULLnn");
60.
61.
62.
main()
63.
64.
65.
66.
67.
68.
for(pos=0;pos<MAXA;pos++) ptabla[pos]=NULL;
69.
70.
do
71.
72.
printf("n*********************************n");
73.
printf("nnTABLA HASHnn
74.
75.
76.
77.
t0.- Salir.ttt");
78.
scanf("%i", &op);
79.
printf("n*********************************n");
80.
81.
switch(op)
82.
83.
case 1:
84.
printf("nIntroduce cadenan");
85.
fflush(stdin);
86.
gets(cadenaux);
87.
clavecadena=clave(cadenaux);
88.
pos=hash(clavecadena);
89.
insertar(&(ptabla[pos]), cadenaux);
90.
for(pos=0;pos<MAXA;pos++)
mostrar(ptabla[pos]);
91.
break;
92.
93.
94.
}while(op!=0);
}
95.
96.
Conceptos de hashing
a) Clave: La clave contiene el valor que permite ubicar, mediante la funcin Hash, la posicino
registro que contiene el resto de informacin asociada. Normalmente la clave es el campo que
identifica en forma nica la informacin. Por ejemplo:
Cdula de Identidad
La idea es seleccionar una funcin que permita obtener una distribucin con el mayor grado
de
uniformidad
posible
para
evitar
colisiones.
Finalmente aclaro que para este programa considere como clave como el nombre de una
persona y la data su apellido, ustedes pueden acomodarle de acuerdo a sus necesidades.
Implementacion en C++
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
using namespace std;
struct registro{
int
nr;
char clave[8];
char data[8];
int sr;
}r, a, s;
struct encabezado{
int nrs;
}ed, ec;
{
int
pos, x;
char rpt;
bool band;
s.sr = r.nr;
fseek(fdd, pos, 0);
fwrite(&s, lr, 1, fdd);
fseek(fdc, 0, 2);
fwrite(&r, lr, 1, fdc);
}
}
cout << " Mas registros [s/n] : "; cin >> rpt; cout << endl;
}while(rpt!='n');
fseek(fdd, 0, 0);
fwrite(&ed, le, 1, fdd);
archivo DISPERSION
fseek(fdc, 0, 0);
fwrite(&ec, le, 1, fdc);
archivo COLISIONES
fclose(fdd);
fclose(fdc);
}
/********************** Funcion Leer ***********************/
void buscar()
{
int
pos, x, nr;
char v_clave[10];
bool band;
fdd = fopen("dispersion.dat", "r");
if(fdd==NULL){
cout << " No se pudo abrir disperson.dat" << endl; return;
}
fdc = fopen("colisiones.dat", "r");
if(fdc==NULL){
cout << " No se pudo abrir colisiones.dat " << endl; return;
}
fflush(stdin);
cout << " Ingrese clave : "; gets(v_clave);
nr = fh(v_clave);
pos = (nr-1)*lr + le;
fseek(fdd, pos, 0);
fread(&r, lr, 1, fdd);
if(strcmp(v_clave, r.clave)==0)
{
cout << " Su data es: " << r.data << endl;
return;
}
else
{
band = false;
x = r.sr;
while( x != -1 )
{
pos = (x-1)*lr + le;
fseek(fdc, pos, 0);
fread(&r, lr, 1, fdc);
if(strcmp(v_clave, r.clave)==0)
{
band = true;
cout << " Su data es : " << r.data << endl;
break;
}
}
if(band == false)
{
cout << " No esta registrado..!" << endl;
}
}
fclose(fdd);
fclose(fdc);
}
void mostrar_archivos()
{
fdd = fopen("dispersion.dat", "r");
if(fdd==NULL){
cout << " No se pudo abrir disperson.dat" << endl; return;
}
fdc = fopen("colisiones.dat", "r");
if(fdc==NULL){
cout << " No se pudo abrir colisiones.dat " << endl; return;
}
fread(&ed, le, 1, fdd);
cout << " Longitud Registro
NR
CLAVE
DATA
SR
\n";
NR
CLAVE
DATA
SR
\n";
fclose(fdd);
fclose(fdc);
}
void menu()
{
cout << "\t\t METODO DE DISPERSION - HASHING \n\n";
cout << "\t 1. Escribir
\n";
\n";
\n";
\n";
";
}
/********************** Funcion Principal ***********************/
int main()
{
int op;
lr = sizeof(struct registro);
le = sizeof( struct encabezado);
do
{
menu(); cin >> op;
cout<<endl;
switch(op)
{
case 1:
escribir(); break;
case 2:
buscar(); break;
case 3:
mostrar_archivos();
case 4:
exit(0);
}
cout <<"\n\n ";
system("pause"); system("cls");
}while(op>0);
return 0;
}