Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Ciencias de la Computación II
Solución de Colisiones
1.1.1. Reasignación
Prueba Lineal:
Básicamente consiste en realizar una búsqueda secuencial después de que se
encuentre una colisión tratando el arreglo como una estructura circular.
“El método de prueba lineal consiste en que una vez que se detecta la colisión, se
recorre el arreglo secuencialmente a partir del punto de colisión, buscando al
elemento. El proceso de búsqueda concluye cuando el elemento es hallado o
cuando se encuentra una posición vacía. El arreglo se trata como una estructura
circular: el siguiente elemento después del último es el primero.” 2 (Cairó, 2006).
Ejemplo:
Tenemos un arreglo de 10 elementos con el cual vamos a usar una función hash
modulo:
H ( k )= ( k mod 10 ) +1
1 2 3 4 5 6 7 8 9 10
43 25 56
Ahora queremos insertar el 35, pero resulta que la función hash nos arroja la
dirección 6 para esta clave lo que genera una colisión porque esta posición ya esta
ocupada. Entonces lo que hacemos es recorrer el arreglo secuencialmente desde el
punto de la colisión hasta que encontremos una posición vacía y pongamos la clave
ahí. La primera posición vacía después de la 6 que fue donde estuvo la colisión es
la 8 entonces ahí va el 35.
1 2 3 4 5 6 7 8 9 10
43 25 56 35
1
Osvaldo Cairó (2006) Estructuras de Datos, Cap. 9.2.8, Pág. 406
2
Osvaldo Cairó, OP CIT, Cap. 9.2.9, Pág. 407
En la posición 7 tampoco esta entonces seguimos.
1 2 3 4 5 6 7 8 9 10
43 25 56 35
1 2 3 4 5 6 7 8 9 10
43 25 56 35
Prueba cuadrática:
“El método de la prueba cuadrática es similar al anterior. La diferencia consiste en
que en el de la prueba cuadrática las direcciones alternativas se generaran como
D+1, D+ 4, D+9, …, D+i 2 en vez de D+i. Esta variación permite una mejor
distribución de las claves que colisionan.”3 (Cairo, 2006).
Ejemplo:
Una vez más tenemos un arreglo de 10 elementos con el cual vamos a usar una
función hash modulo:
H ( k )= ( k mod 10 ) +1
1 2 3 4 5 6 7 8 9 10
43 25 56
Ahora queremos insertar el 35, pero resulta que la función hash nos arroja la
dirección D=6 para esta clave lo que genera una colisión porque esta posición ya
está ocupada. Entonces lo que hacemos es generar una posición nueva a partir de
D+i 2 y empezamos con i=1, entonces tenemos la pocision 6+12 =7. La posición 7
también está ocupada entonces seguimos con i=2 y tenemos 6+22 =10. Esta
posición esta vacía entonces ahí va la clave 35.
1 2 3 4 5 6 7 8 9 10
43 25 56 35
1 2 3 4 5 6 7 8 9 10
43 25 56 35
1 2 3 4 5 6 7 8 9 10
43 25 56 35
3
Osvaldo Cairó (2006) Estructuras de Datos, Cap. 9.2.9, Pág. 409
Como aquí tampoco esta seguimos con i=2 y entonces buscamos en 6+22 =10
1 2 3 4 5 6 7 8 9 10
43 25 56 35
Ejemplo:
Una vez más tenemos un arreglo de 10 elementos con el cual vamos a usar una
función hash modulo:
H ( k )= ( k mod 10 ) +1
1 2 3 4 5 6 7 8 9 10
43 25 56
Ahora queremos insertar el 35, pero resulta que la función hash nos arroja la
dirección D=6 para esta clave lo que genera una colisión porque esta posición ya
está ocupada. Entonces lo que hacemos es tomar la dirección D+1 como si esta
fuera una clave y aplicarle la misma función hash que estamos usando para obtener
otra dirección. Así tenemos la dirección H ( D+ 1 )=( ( 6+1 ) mod 10 ) +1=( 7 mod 10 ) +1=8.
Como esta posición esta vacía insertamos el 35 aquí.
1 2 3 4 5 6 7 8 9 10
43 25 56 35
1 2 3 4 5 6 7 8 9 10
43 54 25 56 35 13
1 2 3 4 5 6 7 8 9 10
43 54 25 56 35 13
1 2 3 4 5 6 7 8 9 10
43 54 25 56 35 13
1 2 3 4 5 6 7 8 9 10
43 54 25 56 35 13
“El método de arreglos anidados consiste en que cada elemento del arreglo tenga
otro arreglo en el cual se almacenen los elementos que colisionan” 5 (Cairo, 2006)
Ejemplo:
Tenemos un arreglo de 10 elementos con el cual vamos a usar una función hash
modulo:
H ( k )= ( k mod 10 ) +1
Cada una de las posiciones de este arreglo tendrá otro arreglo de tamaño V elegido
arbitrariamente, en este caso v=2
Insertando las claves 25, 43 y 56 en nuestro arreglo tenemos:
1 2 3 4 5 6 7 8 9 10
43 25 56
1 2 3 4 5 6 7 8 9 10
43 25 56
35
Este método de solución de polisones es muy sencillo, pero a la vez muy ineficiente
en cuanto a espacio y resulta un problema adicional escoger un tamaño V adecuado
para los arreglos internos.
1.1.3. Encadenamiento
“El método de encadenamiento consiste en que cada elemento del arreglo tenga un
apuntador a una lista ligada, la cual se ira generando y almacenará los valores que
colisionan. Es el método mas eficiente debido al dinamismo propio de las listas.
Cualquiera que sea el numero de colisiones que se presenten, se podrán resolver
sin inconvenientes.”6 (Cairo, 2006).
Ejemplo:
Tenemos un arreglo de 10 elementos con el cual vamos a usar una función hash
modulo:
H ( k )= ( k mod 10 ) +1
Cada una de las posiciones de este arreglo tendrá un apuntador a una lista ligada
que al principio estará vacía.
Insertando las claves 25, 43 y 56 en nuestro arreglo tenemos:
Ahora queremos insertar el 35. La función hash nos arroja la posición 6, en esta
posición ya está la clave 25 entonces recorremos la lista asociada con esta posición
y vemos que esta vacía entonces agregamos la clave 35.
6
Osvaldo Cairó (2006) Estructuras de Datos, Cap. 9.2.11, Pág. 414
Y si quisiéramos insertar la clave 13 la cual aplicando la función hash nos da la
dirección 4 que ya está ocupada, tendríamos:
Por ejemplo, para buscar la clave 13, la función hash nos da la dirección 4, pero en
esta posición no encontramos la clave entonces recorremos la lista asociada a esta
posición hasta encontrar la clave que buscamos.
1.2. Según Sedgewick
“El primer paso en una búsqueda por transformación de claves es computar una
función hash que transforma la clave de búsqueda en una dirección de memoria.
Ninguna función hash es perfecta y dos o mas claves diferentes pueden terminar
con la misma dirección: la segunda parte de una búsqueda hash es un proceso de
solución de colisiones que se encarga de dichas claves.” 7 (Sedgewick, 1983).
Ejemplo:
Sedgewick en su libro propone un ejemplo similar al siguiente:
Supongamos que tenemos un arreglo de 6 posiciones y usando una cierta función
hash insertamos las siguientes claves:
Clave A S E A S
hash 1 0 5 1 0
0 1 2 3 4 5
S A E
Sin embargo, al insertar la cuarta clave, que tiene como dirección hash la posición 1
vemos que se presenta una colisión. Entonces miramos la siguiente posición del
arreglo que es la 2, y como esta esta vacía ponemos la clave ahí.
0 1 2 3 4 5
S A A E
Luego al insertar la ultima clave con dirección hash 0 tenemos otra colisión, al mirar
la siguiente posición del arreglo vemos que esta también esta ocupada entonces
miramos la siguiente a esa y como esa también esta ocupada miramos la siguiente
hasta que llegamos a la posición 3 que no esta ocupada entonces ponemos ahí la
clave S.
0 1 2 3 4 5
S A A S E
7
Robert Sedgewick (1983) Algorithms, Cap. 16, Pág. 201
8
Robert Sedgewick, OP CIT, Cap. 16, Pág. 205
1.2.2. Doble Hash
“La estrategia básica es la misma que la prueba lineal; la única diferencia es que en
lugar de examinar cada entrada sucesiva que sigue a una posición colisionada,
usamos una segunda función hash para obtener un incremento arreglado para usar
en la secuencia de prueba”9 (Sedgewick, 1983).
Sedgewick propone escoger con cuidado una segunda función hash para que al
momento de una colisión apliquemos la segunda función hash a la clave y como
dirección usemos la suma de la primera y segunda dirección hash.
Ejemplo:
Sedgewick en su libro propone un ejemplo similar al siguiente:
Supongamos que tenemos un arreglo de 6 posiciones y usando una cierta función
hash insertamos las siguientes claves:
Clave A S E A S
hash 1 0 5 1 0
Escogemos cuidadosamente una segunda función hash para tratar con las
colisiones. En este ejemplo la segunda dirección hash escogida nos da las
direcciones:
Clave A S E A S
Hash 1 1 0 5 1 0
Hash 2 3 4 2 3 4
0 1 2 3 4 5
S A E
Sin embargo, al insertar la cuarta clave, que tiene como dirección hash la posición 1
vemos que se presenta una colisión. Entonces vemos que el uso de la segunda
función hash en la clave nos da la dirección hash 3, ahora sumamos la primera
dirección hash con esta segunda y nos da la dirección 1+3=4. La posición 4 del
arreglo esta vacía entonces ponemos ahí la clave A.
0 1 2 3 4 5
S A A E
Luego, para insertar la clave S esta también nos genera una colisión en la posición
0. Entonces usamos la segunda dirección hash que es 4 y la suma de ambas
direcciones nos da la dirección 4, pero vemos que esta posición del arreglo también
está ocupada por lo que ahora tomamos esta dirección y le sumamos de nuevo la
segunda dirección hash es decir 4 + 4=8, esta dirección se sale del arreglo que es
de tamaño 6 pero este lo recorremos circularmente por lo que la dirección es
8 mod 6=2, esta posición esta vacía entonces ponemos la clave S ahí.
0 1 2 3 4 5
S A S A E
9
Robert Sedgewick (1983) Algorithms, Cap. 16, Pág. 207
1.2.3. Encadenamiento separado
“El método mas sencillo es simplemente construir una lista ligada, para cada
dirección de la tabla, de los registros que tienen esa misma dirección hash.” 10
(Sedgewick, 1983).
Ejemplo:
Sedgewick en su libro propone un ejemplo similar al siguiente:
Supongamos que tenemos un arreglo de 10 posiciones y que usamos una cierta
función hash para insertar las siguientes claves:
Clave A S E A R C H I N G
hash 1 8 5 1 7 3 8 9 3 7
Como vemos hay varias direcciones hash que se repiten, sin embargo, como en
cada posición del arreglo hay una lista, al momento de insertar una clave en una
posición en la que ya se haya insertado previamente esta se agregará a la lista y no
habrá colisión. Al insertar las claves de nuestro ejemplo tenemos:
0 1 2 3 4 5 6 7 8 9
A C E R S I
A N G H
A continuación, se presenta una serie de ejemplos para cada caso, en cada caso
los ejemplos el tamaño de la tabla será M=13 y la función hash h 1(k) que
utilizaremos será:
10
Robert Sedgewick (1983) Algorithms, Cap. 16, Pág. 202
11
Fernández, J. (2000). TABLAS HASH
Tabla H: Valores ejemplo de claves Kj (Fernández, 2000)
En otras palabras, si las listas se mantienen en orden esto puede verse como una
generalización del método de búsqueda secuencial en listas. La diferencia es que
en lugar de mantener una sola lista con un solo nodo cabecera se mantienen M
listas con M nodos cabecera de forma que se reduce el número de comparaciones
de la búsqueda secuencial. Con los datos de la Tabla H y con la alternativa LIFO, la
tabla quedaría como se muestra en la siguiente figura:
Tabla Hash usando encadenamiento separado (Fernández, 2000)
Cabe aclarar aquí que se debe verificar si la casilla a la que se va a guardar esta
ocupada cada vez que se genere el cálculo, si es así, se continúa con la siguiente
iteración de i, hasta que se encuentre una casilla libre.
12
Fernández, J. (2000). TABLAS HASH
Tabla Hash con Inserción con direccionamiento abierto (Fernández, 2000)
Fernandez, comenta una serie de condiciones para una función re-hashing, mucho
más óptima:
13
Fernández, J. (2000). TABLAS HASH
● que genere una secuencia de valores distinta para dos claves distintas
aunque tenga el mismo valor de función hash,
● que garantice que todas las casillas de la tabla son visitadas.
14
Fernández, J. (2000). TABLAS HASH
2. Solución de Colisiones para Búsquedas Externas
“El uso de áreas independientes para colisiones consiste en definir áreas separadas
-secundarias- de las áreas primarias de almacenamiento, en las que se
almacenaran todos los registros que hayan colisionado. El área de colisiones
puedes estar organizada de diferentes maneras. Una alternativa consiste en tener
en el área común a todas las cubetas. En consecuencia, si se produce una colisión
habrá que buscar a lo largo del área secundaria hasta encontrar el elemento
deseado.”16 (Cairó, 2006).
Ejemplo:
Supongamos que tenemos una estructura de 6 cubetas con 2 registros por cubeta:
0 1 2 3 4 5
Almacenamiento primario
Entonces definimos un área separada de esta solo para los datos que colisionan,
por ejemplo:
0 1 2 3 4 5
Área de Colisiones
0 1 2 3 4 5
12 7 2 15
24 38
Almacenamiento primario
0 1 2 3 4 5
14
Área de Colisiones
15
Osvaldo Cairó (2006) Estructuras de Datos, Cap. 9.3.7, Pág. 430
16
Osvaldo Cairó, OP CIT, Pág. 431
Así, cada vez que haya una colisión, la clave que no se puede insertar en la
respectiva cubeta va al área de colisiones. Por ejemplo, al insertar la clave 54:
0 1 2 3 4 5
12 7 2 15
24 38
Almacenamiento primario
0 1 2 3 4 5
14 54
Área de Colisiones
Ejemplo:
Supongamos que tenemos la misma estructura de 6 cubetas y 2 registros con las
mismas claves que en el anterior ejemplo:
0 1 2 3 4 5
12 7 2 15
24 38
Almacenamiento primario
0 1 2 3 4 5
Área de Colisiones
0 1 2 3 4 5
14
Área de Colisiones
17
Osvaldo Cairó (2006) Estructuras de Datos, Cap. 9.3.7, Pág. 431
Y si intento insertar la clave 54 que hace colisión en la cubeta 0 del almacenamiento
principal entonces la guardo en el bloque 0 del área de colisiones.
0 1 2 3 4 5
54 14
Área de Colisiones
Esto hace la búsqueda en el área de colisiones por que cuando busque una clave
que tenga colisión en una cubeta del almacenamiento principal entonces no tengo
que recorrer toda el área de colisiones buscando la clave colisionada, sino que solo
busco en el bloque correspondiente.
Ejemplo:
Para este método do solución se usa una estructura de cubetas un tanto diferente,
aquí se definen las cubetas y a continuación de cada una de estas un bloque de
colisiones correspondiente a la cubeta. Aquí todo se hace en la misma área de
almacenamiento, no se define ningún área secundaria o algo por el estilo, entonces
por ejemplo si definimos una estructura de 3 cubetas tendremos:
Y cuando alguna clave haga colisión en la cubeta 1 por ejemplo, esta se guarda en
el área de colisiones 1, si resulta que esta área está llena entonces se guarda en el
área de colisiones 2 y así sucesivamente. Así mismo cuando se haga la búsqueda
de una clave en la cubeta 1 y esta no se encuentre aquí entonces se busca en el
área de colisiones 1 y si no se encuentra ahí entonces se busca en el área de
colisiones 2 y así sucesivamente.
Asume que “los métodos de manejo de las tablas hash y sus respectivos métodos
para la resolución de colisiones son aplicables al Hashing dinámico en memoria
secundaria, sin embargo, dice que existen métodos que son aplicables solamente
en memoria secundaria”. 20Esos son: el uso de áreas Independientes y el uso de
áreas de colisiones entre los bloques de almacenamiento primario, en ese
apartado se cita tanto la explicación, como los ejemplos usados en el libro de
Osvaldo Cairó (Estructuras de Datos), los cuales ya se explico en la sección 2.1 de
este mismo informe
19
Frittelli, V., Steffolani, F., Harach, J., Serrano, D., Fernández, J., Scarafia, D., Teicher, R., ... Strub, A. (2013)
Archivos Hash: Implementación y Aplicaciones, Universidad Tecnológica Nacional, Facultad Regional Córdoba
Pág 2.
20
López Takeyas, B. (2007). Administración de Archivos. TRATAMIENTO DE COLISIONES.
Bibliografía
Robert Sedgewick (1983) Algorithms, Addison-Wesley Publishing Company Inc.
Osvaldo Cairó & Silvia Guardati (2006) Estructuras de Datos, Tercera Edicion,
McGraw-Hill Interamericana.
Frittelli, V., Steffolani, F., Harach, J., Serrano, D., Fernández, J., Scarafia, D.,
Teicher, R., ... Strub, A. (2013) Archivos Hash: Implementación y Aplicaciones,
Universidad Tecnológica Nacional, Facultad Regional Córdoba Pág 2.
Recuperado el 05 de noviembre del 2020 desde:
http://conaiisi.unsl.edu.ar/2013/121-493-1-DR.pdf