Sunteți pe pagina 1din 7

Tabla hash

Tabla hash
Una tabla hash o mapa hash 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 la tabla hash utiliza para localizar el valor deseado. 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.

Ejemplo de tabla hash.

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 auto-balanceables son ms rpidos en promedio (tiempo de bsqueda O(log n)) pero la informacin est ordenada en todo momento.

Funcionamiento
Las operaciones bsicas implementadas en las tablas hash son: insercin(llave, valor) bsqueda(llave) que devuelve valor La mayora de las implementaciones tambin incluyen borrar(llave). Tambin se pueden ofrecer funciones como iteracin en la tabla, crecimiento y vaciado. Algunas tablas hash permiten almacenar mltiples valores bajo la misma clave. Para usar una tabla hash se necesita: Una estructura de acceso directo (normalmente un array). Una estructura de datos con una clave Una funcin resumen (hash) cuyo dominio sea el espacio de claves y su imagen (o rango) los nmeros naturales.

Tabla hash

Insercin
1. Para almacenar un elemento en la tabla hash se ha de convertir su clave a un nmero. Esto se consigue aplicando la funcin resumen (hash) a la clave del elemento. 2. El resultado de la funcin resumen ha de mapearse al espacio de direcciones del arreglo que se emplea como soporte, lo cual se consigue con la funcin mdulo. Tras este paso se obtiene un ndice vlido para la tabla. 3. El elemento se almacena en la posicin de la tabla obtenido en el paso anterior. 1. Si en la posicin de la tabla ya haba otro elemento, se ha producido una colisin. Este problema se puede solucionar asociando una lista a cada posicin de la tabla, aplicando otra funcin o buscando el siguiente elemento libre. Estas posibilidades han de considerarse a la hora de recuperar los datos.

Bsqueda
1. Para recuperar los datos, es necesario nicamente conocer la clave del elemento, a la cual se le aplica la funcin resumen. 2. El valor obtenido se mapea al espacio de direcciones de la tabla. 3. Si el elemento existente en la posicin indicada en el paso anterior tiene la misma clave que la empleada en la bsqueda, entonces es el deseado. Si la clave es distinta, se ha de buscar el elemento segn la tcnica empleada para resolver el problema de las colisiones al almacenar el elemento.

Prcticas recomendadas para las funciones hash


Una buena funcin hash es esencial para el buen rendimiento de una tabla hash. Las colisiones son generalmente resueltas por algn tipo de bsqueda lineal, as que si la funcin tiende a generar valores similares, las bsquedas resultantes se vuelven lentas. En una funcin hash ideal, el cambio de un simple bit en la llave (incluyendo el hacer la llave ms larga o ms corta) debera cambiar la mitad de los bits del hash, y este cambio debera ser independiente de los cambios provocados por otros bits de la llave. Como una funcin hash puede ser difcil de disear, o computacionalmente cara de ejecucin, se han invertido muchos esfuerzos en el desarrollo de estrategias para la resolucin de colisiones que mitiguen el mal rendimiento del hasheo. Sin embargo, ninguna de estas estrategias es tan efectiva como el desarrollo de una buena funcin hash de principio. Es deseable utilizar la misma funcin hash para arrays de cualquier tamao concebible. Para esto, el ndice de su ubicacin en el array de la tabla hash se calcula generalmente en dos pasos: 1. Un valor hash genrico es calculado, llenando un entero natural de mquina. 2. Este valor es reducido a un ndice vlido en el vector encontrando su mdulo con respecto al tamao del array. El tamao del vector de las tablas hash es con frecuencia un nmero primo. Esto se hace con el objetivo de evitar la tendencia de que los hash de enteros grandes tengan divisores comunes con el tamao de la tabla hash, lo que provocara colisiones tras el clculo del mdulo. Sin embargo, el uso de una tabla de tamao primo no es un sustituto a una buena funcin hash. Un problema bastante comn que ocurre con las funciones hash es el aglomeramiento. El aglomeramiento ocurre cuando la estructura de la funcin hash provoca que llaves usadas comnmente tiendan a caer muy cerca unas de otras o incluso consecutivamente en la tabla hash. Esto puede degradar el rendimiento de manera significativa, cuando la tabla se llena usando ciertas estrategias de resolucin de colisiones, como el sondeo lineal. Cuando se depura el manejo de las colisiones en una tabla hash, suele ser til usar una funcin hash que devuelva siempre un valor constante, como 1, que cause colisin en cada insercin. Funciones Hash ms usadas:

Tabla hash 1. Hash de Divisin: Dado un diccionario D, se fija un nmero m >= |D| (m mayor o igual al tamao del diccionario) y que sea primo no cercano a potencia de 2 o de 10. Siendo k la clave a buscar y h(k) la funcin hash, se tiene h(k)=k%m (Resto de la divisin k/m). 2. Hash de Multiplicacin Si por alguna razn, se necesita una tabla hash con tantos elementos o punteros como una potencia de 2 o de 10, ser mejor usar una funcin hash de multiplicacin, independiente del tamao de la tabla. Se escoge un tamao de tabla m >= |D| (m mayor o igual al tamao del diccionario) y un cierto nmero irracional (normalmente se usa 1+5^(1/2)/2 o 1-5^(1/2)/2). De este modo se define h(k)= Suelo(m*Parte fraccionaria(k*))

Resolucin de colisiones
Si dos llaves generan un hash apuntando al mismo ndice, los registros correspondientes no pueden ser almacenados en la misma posicin. En estos casos, cuando una casilla ya est ocupada, debemos encontrar otra ubicacin donde almacenar el nuevo registro, y hacerlo de tal manera que podamos encontrarlo cuando se requiera. Para dar una idea de la importancia de una buena estrategia de resolucin de colisiones, considerese el siguiente resultado, derivado de la paradoja de las fechas de nacimiento. Aun cuando supongamos que el resultado de nuestra funcin hash genera ndices aleatorios distribuidos uniformemente en todo el vector, e incluso para vectores de 1 milln de entradas, hay un 95% de posibilidades de que al menos una colisin ocurra antes de alcanzar los 2.500 registros. Hay varias tcnicas de resolucin de colisiones, pero las ms populares son encadenamiento y direccionamiento abierto.

Encadenamiento separado o Hashing abierto


En la tcnica ms simple de encadenamiento, cada casilla en el array referencia una lista de los registros insertados que colisionan en la misma casilla. La insercin consiste en encontrar la casilla correcta y agregar al final de la lista correspondiente. El borrado consiste en buscar y quitar de la lista. La tcnica de encadenamiento tiene ventajas sobre direccionamiento abierto. Primero el borrado es simple y segundo el crecimiento de la tabla puede ser pospuesto durante mucho ms tiempo dado que el rendimiento disminuye mucho ms lentamente incluso cuando todas las casillas ya estn ocupadas. De hecho, muchas tablas hash encadenadas pueden no requerir crecimiento nunca, dado que la degradacin de rendimiento es lineal Ejemplo de encadenamiento. en la medida que se va llenando la tabla. Por ejemplo, una tabla hash encadenada con dos veces el nmero de elementos recomendados, ser dos veces ms lenta en promedio que la misma tabla a su capacidad recomendada. Las tablas hash encadenadas heredan las desventajas de las listas ligadas. Cuando se almacenan cantidades de informacin pequeas, el gasto extra de las listas ligadas puede ser significativo. Tambin los viajes a travs de las listas tienen un rendimiento de cach muy pobre.

Tabla hash Otras estructuras de datos pueden ser utilizadas para el encadenamiento en lugar de las listas ligadas. Al usar rboles auto-balanceables, por ejemplo, el tiempo terico del peor de los casos disminuye de O(n) a O(log n). Sin embargo, dado que se supone que cada lista debe ser pequea, esta estrategia es normalmente ineficiente a menos que la tabla hash sea diseada para correr a mxima capacidad o existan ndices de colisin particularmente grandes. Tambin se pueden utilizar vectores dinmicos para disminuir el espacio extra requerido y mejorar el rendimiento del cach cuando los registros son pequeos.

Direccionamiento abierto o Hashing cerrado


Las tablas hash de direccionamiento abierto pueden almacenar los registros directamente en el array. Las colisiones se resuelven mediante un sondeo del array, en el que se buscan diferentes localidades del array (secuencia de sondeo) hasta que el registro es encontrado o se llega a una casilla vaca, indicando que no existe esa llave en la tabla. Las secuencias de socorridas incluyen: sondeo lineal en el que el intervalo entre cada intento es constante (frecuentemente 1). sondeo cuadrtico en el que el intervalo entre los intentos aumenta linealmente (por lo que los ndices son descritos por una funcin cuadrtica), y doble hasheo en el que el intervalo entre intentos es constante para cada registro pero es calculado por otra funcin hash.
Ejemplo de direccionamiento abierto.

sondeo

ms

El sondeo lineal ofrece el mejor rendimiento del cach, pero es ms sensible al aglomeramiento, en tanto que el doble hasheo tiene pobre rendimiento en el cach pero elimina el problema de aglomeramiento. El sondeo cuadrtico se sita en medio. El doble hasheo tambin puede requerir ms clculos que las otras formas de sondeo. Una influencia crtica en el rendimiento de una tabla hash de direccionamiento abierto es el porcentaje de casillas usadas en el array. Conforme el array se acerca al 100% de su capacidad, el nmero de saltos requeridos por el sondeo puede aumentar considerablemente. Una vez que se llena la tabla, los algoritmos de sondeo pueden incluso caer en un crculo sin fin. Incluso utilizando buenas funciones hash, el lmite aceptable de capacidad es normalmente 80%. Con funciones hash pobremente diseadas el rendimiento puede degradarse incluso con poca informacin, al provocar aglomeramiento significativo. No se sabe a ciencia cierta qu provoca que las funciones hash generen aglomeramiento, y es muy fcil escribir una funcin hash que, sin querer, provoque un nivel muy elevado de aglomeramiento.

Tabla hash

Ventajas e inconvenientes de las tablas hash


Una tabla hash tiene como principal ventaja que el acceso a los datos suele ser muy rpido si se cumplen las siguientes condiciones: Una razn de ocupacin no muy elevada (a partir del 75% de ocupacin se producen demasiadas colisiones y la tabla se vuelve ineficiente). Una funcin resumen que distribuya uniformemente las claves. Si la funcin est mal diseada, se producirn muchas colisiones. Los inconvenientes de las tablas hash son: Necesidad de ampliar el espacio de la tabla si el volumen de datos almacenados crece. Se trata de una operacin costosa. Dificultad para recorrer todos los elementos. Se suelen emplear listas para procesar la totalidad de los elementos. Desaprovechamiento de la memoria. Si se reserva espacio para todos los posibles elementos, se consume ms memoria de la necesaria; se suele resolver reservando espacio nicamente para punteros a los elementos.

Implementacin en pseudocdigo
El pseudocdigo que sigue es una implementacin de una tabla hash de direccionamiento abierto con sondeo lineal para resolucin de colisiones y progresin sencilla, una solucin comn que funciona correctamente si la funcin hash es apropiada. registro par { llave, valor } var vector de pares casilla[0..numcasillas-1] function buscacasilla(llave) { i := hash(llave) mdulo de numcasillas loop { if casilla[i] esta libre or casilla[i].llave = llave return i i := (i + 1) mdulo de numcasillas } } function busqueda(llave) i := buscacasilla(llave) if casilla[i] est ocupada // llave est en la tabla return casilla[i].valor else // llave no est en la tabla return no encontrada function asignar(llave, valor) { i := buscacasilla(llave) if casilla[i] est ocupada casilla[i].valor := valor else { if tabla casi llena { hacer tabla ms grande (nota 1) i := buscacasilla(llave)

Tabla hash } casilla[i].llave := llave casilla[i].valor := valor } }

Nota
[1] La reconstruccin de la tabla requiere la creacin de un array ms grande y el uso posterior de la funcin asignar para insertar todos los elementos del viejo array en el nuevo array ms grande. Es comn aumentar el tamao del array exponencialmente, por ejemplo duplicando el tamao del array.

Enlaces externos
Artculos e implementaciones
Artculo donde se explica la implementacin en C y un anlisis de costo-beneficio de una tabla hash (http:// urtevolution.com.ar/blog/?p=1).

Fuentes y contribuyentes del artculo

Fuentes y contribuyentes del artculo


Tabla hash Fuente: http://es.wikipedia.org/w/index.php?oldid=48130643 Contribuyentes: Arlekean, Bernard77, Camilo, Caos, Cesarsorm, Comae, Dem, Diegusjaimes, Dodo, Fortran, Humbefa, Jfgarcia, Julie, LeonardoGregianin, Loboferoz8, Maldoror, Roberto Parrillas, Sms, Vicucha, Wastingmytime, 46 ediciones annimas

Fuentes de imagen, Licencias y contribuyentes


Imagen:Tabla hash1.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Tabla_hash1.png Licencia: Creative Commons Attribution-ShareAlike 3.0 Unported Contribuyentes: Cesarsorm Imagen:Tabla hash2.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Tabla_hash2.png Licencia: Creative Commons Attribution-ShareAlike 3.0 Unported Contribuyentes: Cesarsorm Imagen:Tabla hash 3.png Fuente: http://es.wikipedia.org/w/index.php?title=Archivo:Tabla_hash_3.png Licencia: Creative Commons Attribution-ShareAlike 3.0 Unported Contribuyentes: Cesarsorm

Licencia
Creative Commons Attribution-Share Alike 3.0 Unported http:/ / creativecommons. org/ licenses/ by-sa/ 3. 0/

S-ar putea să vă placă și