Tabla Hash
Tabla Hash
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.
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.
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.
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.
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
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)
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).
Licencia
Creative Commons Attribution-Share Alike 3.0 Unported http:/ / creativecommons. org/ licenses/ by-sa/ 3. 0/