Tema 5 El TAD Tabla Dispersa Objetivos ! Conocer el TAD Tabla Dispersa como estructura eficiente de almacenamiento ! Conocer las funciones de dispersión, así como los métodos de gestión de colisiones más habituales ! Implementar una tabla dispersa con gestión de colisiones mediante encadenamiento Contenidos 5.1 Conceptos 5.2 Funciones de dispersión 5.3 Resolución de colisiones 5.4 Especificación algebraica 5.5 Implementación Duración ! 2 clases (3 h) Algoritmos y Estructuras de Datos II Tema 5 I.T. en Informática de Gestión/Sistemas Universidad de Huelva 1 El TAD Tabla Dispersa Bibliografía ! Estructuras de datos: especificación, diseño e implementación Autor: Xavier Franch Gutiérrez Editorial : Ediciones UPC, 1999 ! Estructuras de datos. Algoritmos, abstracción y objetos Autor: Luis Joyanes Aguilar, Ignacio Zahonero Martínez Editorial: McGraw-Hill Págs. 622-645 Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 2 El TAD Tabla Dispersa Tema 5 5.1 Conceptos ! El TAD de las funciones f: Dclaves " Dvalores, donde Dclaves representa el conjunto de claves y Dvalores el conjunto de valores es conocido, en el ámbito de las estructuras de datos, con el nombre de tabla (también conocido como tipo asociativo, funcional o diccionario) ! Una tabla se define como un conjunto de pares (c, v), donde c se denomina clave y v representa el valor asociado a la clave. En este conjunto no puede haber dos pares con la misma clave, es decir, las claves son únicas ! Las principales operaciones que suelen realizarse sobre valores de tipo tabla son: # crear una tabla vacía # insertar un nuevo par (c, v) # comprobar la existencia de una clave en la tabla # consultar el valor v asociado a una clave c # modificar el valor v asociado a una clave c # borrar un par (c, v) # comprobar si la tabla está vacía Algoritmos y Estructuras de Datos II Tema 5 I.T. en Informática de Gestión/Sistemas Universidad de Huelva 3 El TAD Tabla Dispersa ! Si el conjunto de las claves está formado por un número relativamente pequeño de números naturales (cercanos entre ellos) y no hay dos elementos con la misma clave, se puede utilizar una representación mediante una tabla (tabla de acceso directo) ! Si las claves no son numéricas o no se cumple lo anterior, debería existir una función inyectiva que transforme cada clave en un número comprendido en el subrango [1..máximo] de la tabla TV f: Dclaves " 1.. max valor 1 valor 2 claves c1 c10 valor 6 c8 valor 8 c6 valor 10 max Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 4 El TAD Tabla Dispersa Tema 5 ! Todas las operaciones son de orden O(1). En contraposición, los principales inconvenientes de este tipo de representación son: # desaprovechamiento de la memoria si el número de elementos almacenados en la tabla T es pequeño en relación con el número posible de claves # es difícil encontrar funciones inyectivas que transformen claves en índices ! Una alternativa a las tablas de acceso directo son las tablas dispersas o tablas hash, que consiguen, aproximadamente, un coste constante para todas las operaciones sobre tablas Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 5 El TAD Tabla Dispersa Tema 5 ! Una tabla dispersa es una estructura similar a la tabla de acceso directo ! En lugar de utilizar la clave para indexar directamente sobre la tabla, el índice es calculado a partir de la clave utilizando una función de dispersión (h) T h: Dclaves " 1.. max h(c24) h(c5) 1 valor24 valor5 claves h(c3) c78 c5 función de dispersión (h) c24 h(c78) c3 valor3 valor78 max Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 6 El TAD Tabla Dispersa Tema 5 ! No es necesario que la función h sea inyectiva. Se dividen las claves en n clases de equivalencia. En cada clase se encuentran las claves que al aplicarles la función h devuelven el mismo valor (posición en la tabla) ! h(ci) es el índice o valor de dispersión calculado por h al suministrarle la clave ci ! Se dice que ci se dispersa en la posición T[h(ci)] de la tabla dispersa T ! De esta forma se soluciona el problema de las claves no numéricas o números muy grandes ! Uno de los aspectos fundamentales en las tablas dispersas consiste en realizar una buena elección de la función h ! Esta función debe distribuir las claves esperadas de la manera más uniforme posible en el rango 1..max, de forma que la probabilidad de que 2 claves distintas (c1 ≠ c2) obtengan el mismo valor de h (h(c1) = h(c2)) sea lo más baja posible Algoritmos y Estructuras de Datos II Universidad de Huelva 7 El TAD Tabla Dispersa Tema 5 ! I.T. en Informática de Gestión/Sistemas Para definir una tabla dispersa, el programador debe tomar 2 decisiones importantes 1. Elegir la función h. Como la función no es inyectiva es posible que una posición calculada para una clave c ya esté ocupada (colisión) 2. Seleccionar un método para resolver las colisiones a. Dispersión abierta. Los elementos que colisionan se sitúan en una lista a partir de la posición calculada b. Dispersión cerrada. Los elementos que colisionan se sitúan en la propia tabla. Hace falta un algoritmo de recolocación Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 8 El TAD Tabla Dispersa Tema 5 5.2 Funciones de dispersión ! Características de una función de dispersión 1. Rapidez de cálculo 2. Exhaustividad. Todo índice o valor de dispersión debe tener asociada, como mínimo, una clave 3. Distribución uniforme. Todos los valores de dispersión deben tener aproximadamente el mismo número de claves asociadas Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 9 El TAD Tabla Dispersa Tema 5 Traducción de cadenas a enteros ! Suma de los caracteres • A cada carácter se le calcula su valor decimal • Se suman los números obtenidos c = “pérez” ! num (c) = dec (‘p’) + dec (‘é’) + dec (‘r’) + dec (‘e’) + dec (‘z’) = 112 + 130 + 114 + 101 + 122 = 579 Suma ponderada de los caracteres • La cadena se trata como un entero en base n (n ≡ número de caracteres del código) c = “pérez” num (c) = dec (‘p’) * 2564 + dec (‘é’) * 2563 + dec (‘r’) * 2562 + dec (‘e’) * 256 + dec (‘z’) = “número muy grande” Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 10 El TAD Tabla Dispersa Tema 5 Funciones que obtienen valores en un intervalo ! División Se calcula el resto de dividir el número entre N (N ≡ tamaño de la tabla) h (c) = c mod N Puede funcionar mal, por ejemplo si N = 10 y casi todas las claves son múltiplos de 10, habrá muchas colisiones ya que para casi todas las claves h(c) = 0 NOTA: el N más apropiado es un número primo ! Método del cuadrado Consiste en calcular el cuadrado de la clave c. El índice se obtiene de los dígitos de c2 que ocupan una determinada posición Algoritmos y Estructuras de Datos II Tema 5 265 " 70225 h (265) = 22 1340 " 1795600 h (1340) = 956 777 " 603729 h (777) = 372 I.T. en Informática de Gestión/Sistemas Universidad de Huelva 11 El TAD Tabla Dispersa Funciones que obtienen valores en un intervalo ! Plegamiento • Consiste en dividir la clave c en partes de igual número de dígitos (la última puede tener menos dígitos) y operar con ellas, tomando como índice los dígitos menos significativos del resultado • La operación entre las partes puede hacerse por medio de sumas o multiplicaciones h (152635) = 15 + 26 + 35 = 76 h (934058) = 93 + 40 + 58 = 191; h (934058) = 91 Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 12 El TAD Tabla Dispersa Tema 5 5.3 Resolución de colisiones 5.3.1 Dispersión abierta: por encadenamiento ! Todos los pares (clave, valor) cuya clave es asignada por la función de dispersión h a una misma posición, se almacenan en una lista asociada a dicha posición ! La zona de memoria dinámica donde se almacenan las listas asociadas a cada posición de la tabla se denomina: zona de desbordamiento T (c1, v1) 1 h 2 Función de Dispersión (c2, v2) . . (c3, v3) n Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 13 El TAD Tabla Dispersa Tema 5 5.3.2 Dispersión cerrada: recolocación en la tabla ! Consiste en almacenar los pares (clave, valor) cuya entrada primaria (índice) ya esté ocupada (colisión), en otra posición libre de la propia tabla ! Las colisiones se resuelven calculando una secuencia de huecos de dispersión " se evita el uso de estructuras auxiliares ! Los pares (c, v) recolocados ocupan posiciones de futuras claves. El funcionamiento de este método será bueno si el factor de carga α se mantiene por debajo de 0.9 # Factor de carga α= N / max • N: nº de pares (c, v) almacenados en la tabla • max: tamaño de la tabla ! El factor de carga indica el nivel de ocupación de la tabla con pares almacenados # Si N=max " α=1 # Si α<1" Hay menos pares que posiciones # Si α>1" Hay más pares que posiciones Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 14 El TAD Tabla Dispersa Tema 5 5.4 Especificación algebraica espec TablasDispersas usa booleanos parámetro formal género clave operaciones _ = _ : clave clave " booleano fpf Gen (tabla) = { tVacia, asigna } Obs (grafo) = {esta?, observa, elimina} género tablaD operaciones tVacía: " tablaD asigna: tablaD clave valor " tablaD esta?: tablaD clave " booleano parcial observa: tablaD clave " valor elimina: tablaD clave " tablaD Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 15 El TAD Tabla Dispersa Tema 5 dominios de definición t: tablaD; c: clave observa(t,c) está definido sólo si esta?(t,c) ecuaciones t: tablaD; c, c1,c2: clave; v, v1,v2: valor asigna (asigna (t, c1, v1), c2, v2) = si c1 = c2 entonces asigna (t, c2, v2) sino asigna (asigna (t, c2, v2), c1, v1) fsi esta?(tvacia, c) = falso esta?(asigna (t, c1, v), c2) = (c1 = c2) o esta? (t, c2) observa (asigna (t, c1, v), c2) = si c1 = c2 entonces v sino observa (t, c2) fsi elimina(tvacia, c) = falso elimina(asigna (t, c1, v), c2) = si c1 = c2 entonces elimina(t, c2) sino asigna(elimina (t, c2), c1, v) fsi Algoritmos y Estructuras de Datos II I.T. en Informática de Gestión/Sistemas Universidad de Huelva 16 El TAD Tabla Dispersa Tema 5 5.5 Implementación ! Resolución de colisiones por encadenamiento # Si el factor de carga α es pequeño, la resolución de colisión por encadenamiento es rápida → las listas de desbordamiento son cortas # Si la tabla tiene dimensión max y hay N pares (clave, valor), con una función h uniforme, la longitud media de las listas es N max ! Implementación de la clase tablaDispersa: par = clase público constructor creaPar(c: clave; v: elemento); { clave admite comparaciones de igualdad } función getClave: clave; función getValor: elemento; privado clave: clave; valor: elemento fclase; Algoritmos y Estructuras de Datos II Tema 5 Implementación de los métodos creaTablaVacía y asigna acción tablaDispersa.creaTablaVacía; var i: 0..max – 1; fvar; para i := 0 hasta max – 1 hacer t[i].creaLista fpara facción; Algoritmos y Estructuras de Datos II tablaDispersa = clase publico constructor creaTablaVacía; acción asigna (p: par); función observa (c: clave; var v: valor):booleano; acción elimina (c: clave); privado constante max = ...; t: tabla [0..max –1] de lista<par>; fclase; I.T. en Informática de Gestión/Sistemas Universidad de Huelva 17 El TAD Tabla Dispersa acción tablaDispersa.asigna(p: par); var entrada: 0..max – 1; parAct: par; claveAct: clave; i, long: entero; fvar; entrada := h(p.getClave); si t[entrada].esVacía entonces t[entrada].creaUnitaria(p) sino i := 1; long := t[entrada].longitud; parAct := t[entrada].observaIzq; claveAct := parAct.getClave; mientras (i < long) y (claveAct ≠ p.getClave) hacer i := i + 1; parAct := t[entrada].observa(i); claveAct := parAct.getClave fmientras; si claveAct = p.getClave entonces t[entrada].modifica(i, p) sino t[entrada].añadeIzq(p) fsi fsi ffunción; I.T. en Informática de Gestión/Sistemas Universidad de Huelva 18 Tema 5 El TAD Tabla Dispersa Implementación de los métodos elimina y observa acción tablaDispersa.elimina (c: clave); var entrada: 0..max – 1; parAct: par; claveAct: clave; i, long: entero; fvar; entrada := h(p.getClave); si no t[entrada].esVacía entonces i := 1; long := t[entrada].longitud; parAct := t[entrada].observaIzq; claveAct := parAct.getClave; mientras (i < long) y (claveAct ≠ p.getClave) hacer i := i + 1; parAct := t[entrada].observa(i); claveAct := parAct.getClave fmientras; si claveAct = p.getClave entonces t[entrada].elimina(i) fsi fsi facción; Algoritmos y Estructuras de Datos II función tablaDispersa.observa (c: clave; var v: valor):booleano; var entrada: 0..max – 1; parAct: par; claveAct: clave; i, long: entero; fvar; entrada := h(p.getClave); si t[entrada].esVacía entonces observa := falso; sino i := 1; long := t[entrada].longitud; parAct := t[entrada].observaIzq; claveAct := parAct.getClave; mientras (i < long) y (claveAct ≠ p.getClave) hacer i := i + 1; parAct := t[entrada].observa(i); claveAct := parAct.getClave fmientras; si claveAct = p.getClave entonces v := parAct.getValor; observa := verdad sino observa := falso fsi fsi facción; I.T. en Informática de Gestión/Sistemas Universidad de Huelva 19