Sie sind auf Seite 1von 5

Introduccin

La bsqueda binaria proporciona un medio para reducir el tiempo requerido


para buscar en una lista. Este mtodo, sin embargo, exige que los datos
estn ordenados y siempre depende del nmero n de elementos que
conforman el conjunto de datos.
Surge entonces una pregunta, es posible lograr una bsqueda de O(1)?, es
decir, una bsqueda que tome el mismo tiempo para buscar cualquier
elemento de una lista. La respuesta es s. Para ello se utiliza la tcnica
hashing.Este mtodo se conoce como transformacin de claves (clavedireccin) y consiste en convertir el elemento almacenado (numrico o
alfanumrico) en una direccin (ndice) dentro de un arreglo, de manera que
se puede acceder al elemento directamente.
Ejemplo.
Vamos a partir de un sencillo ejemplo. Supongamos que tenemos una lista
de empleados de una pequea empresa. Cada empleado tiene asignado un
nmero de identificacin de 0 hasta 99. Entonces se necesitara un vector
de tamao fijo de 100 posiciones para almacenar los empleados. Ahora,
podramos tener una relacin directa entre el valor clave de cada empleado
con el ndice del arreglo. As:

De esta forma es posible acceder directamente a la informacin de cada


empleado conociendo el nmero de identificacin de cada empleado. Por
ejemplo, si se quiere acceder al empleado con identificacin 3, simplemente
se utilizara la instruccin: arreglo[3].
Sin embargo, hacer esta correspondencia en la prctica no es posible, ya
que generalmente los nmeros de identificacin son nmeros largos como
es el caso de los nmeros de cdula. Entonces, no sera posible crear un
arreglo tan grande para contener tal cantidad de elementos.
Qu alternativa entonces existe?
Una alternativa sencilla para no crear arreglos enormes, sera usar los dos
ltimos campos del campo clave. Por ejemplo, en el caso de la cdula
utilizar los dos ltimos campos. As pues, si la cdula es 98393274, esta
cdula se almacenara en el arreglo en la posicin 74.
Para ello, se necesita tener una funcin hash, que determine, a partir del
campo clave, en qu posicin del arreglo estar cada objeto. La funcin
hash, determinar el mtodo de acceso al arreglo.
En este caso, la funcin hash aplicar la operacin: CLAVE MOD 100. As por
ejemplo, si la clave es 98393204, la funcin hash devolver que se debe
acceder a la posicin 4 (98393204 MOD 100 = 4).
De la siguiente manera:

A continuacin se da el cdigo fuente en java de cmo sera la funcin hash:


public int funcionHash(int clave){
return clave%100;
}
El problema de esta tcnica son las colisiones, lo cual se explica a
continuacin.
Colisiones
El esquema explicado anteriormente de la funcin hash, no garantiza
direcciones nicas (colisiones). Por ejemplo, para las claves 98393204 y
76236304, la funcin hash arrojara la misma posicin: 4.
Las colisiones son imposibles de evitar, lo que se debe tener en cuenta es
que una buena funcin hash, debe minimizar las colisiones extendiendo los
registros uniformemente a travs de la tabla.
Existen varias alternativas para manejar las colisiones. Las cuales se
explican a continuacin.
Mtodo 1: Hashing y bsqueda

Esta tcnica es sencilla, consiste en almacenar cada elemento colisionado


en el siguiente espacio disponible. Por ejemplo, si queremos almacenar
nuevo registro con la clave 366702003, al aplicar la funcin hash dara la
posicin 3. Suponiendo que esta ya est ocupada, el algoritmo propone
buscar el siguiente espacio disponible (donde haya null) para poder
almacenar el dato. Si la bsqueda llega al final y estn todas las posiciones
ocupadas, se debe buscar desde el principio. La Figura 3, ilustra este
ejemplo, donde se puede apreciar que la posicin 3 devuelta por la funcin
hash ya est ocupada, por lo tanto, el nuevo dato debera almacenarse en la
siguiente posicin libre, en este caso, la posicin 4 (null).

Para buscar un elemento con esta tcnica, se aplica la funcin hash sobre la
clave, luego se compara la clave devuelta con la clave real. Si las claves no
coinciden, se hace una bsqueda secuencial comenzando por la siguiente
posicin del array. Nuevamente, si se llega al final del vector, se sigue
buscando desde el principio.
Mtodo 2: Rehashing
Si el primer clculo de la funcin hash produce una colisin, se usa la
direccin transformada como entrada para una funcin rehash y se calcula
una nueva direccin. Un ejemplo de funcin rehash sencilla sera: (Direccin
ocupada + 1) mod 100. Si el resultado sigue siendo un espacio ocupado, se
puede aplicar la funcin rehashing hasta obtener un espacio disponible.

La clave 36670003 es pasada como entrada a la funcin hash, sta arroja la


direccin 3, la cual en el caso est ocupada; por lo tanto, tendra que pasar
por la funcin rehashing. En este caso la funcin rehashing devolvera la
nueva direccin 4. Si el valor 4, est ocupado, se aplica la funcin rehashing
hasta obtener un espacio disponible.
Mtodo 3: mltiples espacios
Esta tercer tcnica, consiste en modificar la tabla de tal forma que en lugar
de almacenar un objeto en cada posicin, se pueda almacenar en cada
espacio varios objetos. De esta forma, varias direcciones colisionadas
arrojadas por la funcin hash se pueden almacenar en el mismo espacio.

Se puede apreciar que la funcin hash devuelve la direccin 3. Como en la


posicin 3 ya est almacenado con un objeto empleado con cdula:
3353503, entonces, simplemente el nuevo objeto se encadena a ste.
La idea general de usar la clave para determinar la direccin del registro es
una excelente idea, pero se debe modificar de forma que no se desperdicie
tanto espacio. Esta modificacin se lleva a cabo mediante una funcin que
transforma una clave en un ndice de una tabla y que se denomina funcin
de Randomizacin o Hash.

Si H es una funcin hash y X es un elemento a almacenar, entonces H(X) es


la funcin hash del elemento y se corresponde con el ndice donde se debe
colocar X. En nuestro ejemplo, la funcin hash sera H(X)=X % 53 (funcin
resto).
Los valores generados por H deben cubrir todo el conjunto de ndices de la
tabla. Adems, el tamao de la tabla debe ser un poco ms grande que el
nmero de elementos que han de ser insertados, aunque queden posiciones
de la tabla sin uso.
El mtodo anterior tiene una deficiencia: suponer que dos elementos X e Y
son tales que H(X) = H(Y). Entonces, cuando un el elemento X entra en la
tabla, ste se inserta en la posicin dada por su funcin Hash, H(X). Pero
cuando al elemento Y le es asignado su posicin donde ser insertado
mediante la funcin hash, resulta que la posicin que se obtiene es la
misma que la del elemento X. Esta situacin se denomina colisin o choque.
Una buena funcin Hash ser aquella que minimiza las colisiones, y que
distribuya los elementos uniformemente a travs del arreglo. Esta es la
razn por la que el tamao del arreglo debe ser un poco mayor que el
nmero real de elementos a insertar, pues cuanto ms grande sea el rango
de la funcin de randomizacin, es menos probable que dos claves generen
el mismo valor de asignacin o hash, es decir, que se asigne una misma
posicin a ms de un elemento.
Habr que llegar a un compromiso entre Eficiencia en Espacio-Tiempo: el
dejar espacios vacos en la tabla es una deficiencia en cuanto a espacio,
mientras que reduce la necesidad de resolver los casos de choque en la
asignacin, y por lo tanto es ms eficiente en trminos de tiempo.

Una solucin al problema de las colisiones: Zona de desbordamiento.


Se trata de mantener una zona reservada para aquellos elementos que
llegan a colisionar, de manera que cuando se produzca una colisin el
elemento se va a localizar en esta zona de desbordamiento.
Al realizar la bsqueda y comprobar si el elemento buscado est en la
posicin dada por su tabla hash, si esa posicin ya est ocupada por otro
elemento con el mismo valor de hashing, se seguir buscando a partir del
inicio de la zona de desbordamiento de manera secuencial, hasta encontrar
el elemento o llegar al final de dicha zona de desbordamiento.
Siguiendo con el ejemplo, para cada cdigo se obtena el residuo (resto) de
su divisin por un nmero primo (en este caso el 53). Es recomendable usar
nmeros primos ya que que reduce la probabilidad de colisin al establecer
funciones del tipo: H(X) = (X % primo)
Ahora bien, cul valor primo escoger? En este ejemplo se manejan 30
cdigos, de modo que ese valor debe ser superior a 30, y que su magnitud
se acerque al doble de elementos, por ello una buena opcin era el 53 (o
tambin el 61). Valores primos muy cercanos a la cantidad original de datos
da lugar a demasiadas colisiones y un valor primo grande (por ejemplo, 97)
da lugar a un considerable desperdicio de espacio (casillas vacas).

Cmo nos quedaran ubicados los elementos en el vector? Hay que tener
en cuenta algo ms: como el valor primo utilizado en la funcin de Hashing
fue el 53, inicialmente el vector destino tendra 53 casillas, pero a eso hay
que agregarle las casillas de la zona de desbordamiento, de modo que
habra que aumentar esas casillas alrededor de un 25%, y en ese caso
nuestro vector quedara con 53 * 1.25 = 66.25, o sea 66 casillas en total.
Las 53 primeras almacenarn los cdigos segn la posicin que resulte al
aplicar la funcin de Hashing, las 13 restantes representan la zona de
desbordamiento a donde irn los cdigos que colisionen.
Veamos un grfico de cmo quedaran los cdigos en ese vector:

http://escritura.proyectolatin.org/estructura-de-datos/tipos/

Das könnte Ihnen auch gefallen