HASH TABLE
-
Upload
alexander-pl -
Category
Documents
-
view
55 -
download
0
description
Transcript of HASH TABLE
-
5/25/2018 HASH TABLE
1/17
Clase 31
Hash ing (Dispersin)
Motivacin
Podemos realizar una bsqueda en un tiempo mejor que O( lg n )?
La operacin de memoria de un ordenador lorealiza en mucho menos tiempo: toma unaclave (la direccin de la memoria) para insertar
o recuperar elementos de datos (la palabra dela memoria) en un tiempo constante (O( 1 )).
Los tiempos de acceso para la memoria de un
ordenador no aumentan con el tamao o la
proporcin de la memoria.
2
-
5/25/2018 HASH TABLE
2/17
Direccionamiento directo
El acceso a la memoria del ordenador es uncaso especial de una tcnica denominadadi recc ionamiento di rectoen la que la claveconduce directamente al elemento de datos.
El almacenamiento de datos en arraystambines otro ejemplo de este mtodo, en el que el
ndice del arrayjuega el papel de la clave.
El problema de los esquemas de direccionamiento
directo reside en que requieren un almacenamiento
equivalente al rango de todas las posibles claves yno el proporcional al nmero de elementos que
realmente se almacenan.
3
Ejemplo de direccionamiento directo
Utilicemos el ejemplo de los nmeros de la seguridad social.
Un esquema de direccionamiento directo paraalmacenar la informacin de ingresos de loscontribuyentes estadounidenses requerira una
tabla de 1.000.000.000 de entradas, puesto que elnmero de la seguridad social es de 9 dgitos.
No importa si esperamos almacenar datos de100 o de 100.000.000 contribuyentes.
El esquema de direccionamiento directo
necesitar una tabla que pueda incluir mil
millones de entradas potenciales.4
-
5/25/2018 HASH TABLE
3/17
Hashing
El hashinges una tcnica que ofrece una
velocidad comparable a la del direccionamientodirecto (O(1)) con requisitos de memoria (O(n))mucho ms gestionables, donde nes el
nmero de entradas almacenadas en la tabla.
El hashingutiliza una funcin para generar un
cdigo hashpseudoaleatorio a partir de la clave
del objeto y luego utiliza este cdigo (~direccin
directa) para indexar en la tabla hash.
5
Ejemplo de hash ing
Suponga que queremos una pequea tablahashcon capacidad de 16 entradas paraalmacenar palabras en ingls.
Necesitaremos una funcin hashque asigne las palabras a los enteros 0, 1, ..., 15.
Normalmente, la tarea se divide en crearuna funcin hashen dos partes:
1. Asignar la clave a un entero.
2. Asignar el entero "aleatoriamente" o en un rango bien
distribuido de enteros ( { 0, ..., m-1 }, donde m es la
capacidad o el nmero de entradas que se utilizarn para
indexar en la tabla hash.
6
-
5/25/2018 HASH TABLE
4/17
Ejemplo de cdigo hash
Como ejemplo, considere un cdigo hashque
toma el valor numrico del primer carcter de lapalabra y lo agrega al valor numrico del ltimocarcter (paso 1) para, despus, tomar el restomod16 (paso 2).
Por ejemplo, el valor numrico de una "c" es 99
y el de una "r" es 114. Por lo que, "car" se
dispersara en (99 + 114) mod 16 = 5.
7
Diagrama de cdigo hash
0 Universo1
2de claves3
4car5
6
7dorm89
10
11house
12
13
14color15
8
-
5/25/2018 HASH TABLE
5/17
Colisiones
"car" y "color" se dispersan al mismo valorutilizando esta funcin hash, ya que tienen lamisma letra inicial y final. Nuestra funcin hashpodra no ser tan "aleatoria" como debiera.
Pero si n > m, los cdigos hashduplicados,tambin conocidos como colisiones, soninevitables.
De hecho, incluso con n < m, las colisionespueden seguir siendo consecuencia delargumento von Mises(tambin conocido como
la paradoja del cumpleaos: si hay 23 personasen una habitacin, la probabilidad de que almenos dos de ellas cumplan los aos el mismoda supera el 50%).
9
Tareas de hashing
1. Disear una funcin hashadecuada paraasignar cdigos hasha las claves, de tal forma
que un conjunto no aleatorio de claves genereun conjunto equilibrado aleatorio de cdigohash;
Si los cdigos hashno son aleatorios, el nmeroexcesivo de colisiones agolpar las claves en la
misma direccin directa.
2. Tratar las posibles colisiones queaparezcan despus del hashing.
10
-
5/25/2018 HASH TABLE
6/17
Encadenamiento para evitar colisiones
Elencadenam ientoes un enfoque sencillo y eficaz para
gestionar las colisiones.
En una tabla hashcon encadenamiento, las entradas de la
tabla (normalmente llamadas s lo tso bucke ts, no contienen
los propios objetos almacenados, sino listas enlazadas de
los objetos.
Los objetos con claves colisionadas se insertan el la misma lista.
La insercin, la bsqueda y la eliminacin se convierten en
procesos de 2 pasos:
1. Utilizar la funcin hashpara seleccionar el s lo tadecuado.
2. Realizar la operacin necesaria en la lista enlazada a la
que se hace referencia en dicho s lo t.
11
Ilustracin de encadenamiento
claves = { a, b, c, d, aa, bb, cc, dd }
0 bb c
1 aa
2 dd b
3 cc d a
12
-
5/25/2018 HASH TABLE
7/17
Factor de carga y rendimiento
La relacin entre el nmero de elementos almacenados, n, y
el nmero de s lo tsde la tabla, m, n /m, recibe el nombre def ac to r de carga.
Como las listas enlazadas a las que se hace referencia enlos s l ot s hashpueden contener un nmero arbitrario deelementos, no existe lmite en la capacidad de la tabla hashque utiliza el encadenamiento.
Si la funcin hashempleada no distribuye bien las claves,el rendimiento de la tabla disminuir.
El peor caso para una tabla hashy para un rbol binario esel de la lista enlazada. Esto ocurre cuando todas las clavesse dispersan al mismo slot.
Sin embargo, dada una buena funcin hash, se puede
demostrar que una tabla hashcon encadenamiento y unfactor de carga L puede realizar las operaciones bsicas deinsercin, bsqueda y eliminacin en un tiempo O( 1 + L ).
Para una mayor eficacia, el factor de carga debe ser 0.75
Iteradores de la tabla hash
La iteracin en una tabla hashtambin esun proceso de dos pasos.Para cada slot co n una l ist enlazada, hl ist
Para cada elemento , i , en hlist
Devolver i
Como los cdigos hashasignan elementos a s lots
"aleatoriamente" y no estamos ordenando laslistas enlazadas, dicha iteracin no estordenada.
El orden y la localidad son una de lascaractersticas buscadas para la velocidad deacceso en las tablas hash.
14
-
5/25/2018 HASH TABLE
8/17
Eficacia del iterador
El tiempo que se tarda en iterar una tabla conpocas colisiones es proporcional a la capacidad
de la tabla o al nmero de s lots, no al nmero deelementos almacenados.
El tiempo aproximado que tardar en iterarse
una tabla de gran capacidad con pocoselementos ser equivalente al de una tabla en laque el nmero de elementos almacenados seasemeje al nmero de s lots.
Las aplicaciones tradicionales de tablas hashno
requieren acceso ordenado ni la posibilidad de
iterar.15
Aplicaciones tpicas de tablas hash
Uno de los usos clsicos de las tablas hashes gestionar la
tabla de smbolos de intrpretes y compiladores. Los
nombres de smbolos (p.ej, nombres de variables) son la
clave y los datos de smbolos (p.ej., tipo, ubicacin, etc.)
estn contenidos en el objeto almacenado. La necesidad
principal es la bsqueda rpida.
Si se requiere una lista ordenada de la tabla de smbolos (yahora es ms difcil que nuca) puede ofrecerse en un
segundo anlisis.
Otros usos tpicos de tablas hashsuelen incluir la gestin
de una clase de datos por una clave arbitraria, como el
nmero de la seguridad social, el nmero de cuenta o el
nmero de DNI.
16
-
5/25/2018 HASH TABLE
9/17
Funciones hash
Las funciones hasheficaces son cruciales parauna buena implementacin de tablas hash.
Solemos querer almacenar claves que soncualquier cosa excepto aleatorias. Piense enalmacenar nombres de personas con el apellidoen primer lugar. En EE.UU. habr muchas clavesque comiencen por "Smith, ..." y que terminenpor "..., John". Necesitaramos que la funcin dehashingpara los nombres obtuviese comoresultado una distribucin de las entradas"Smith" en s lotsdispersos independientes yque distinguiese "Smith, John" de, por ejemplo,"Harward, Judson".
17
Funcioneshash1y hash2
Asumamos que queremos almacenarnobjetos de un universo Ude Nobjetosdistintos con Nclaves distintas en una tablahas h T, con m slots. Asumamos de momento
que n
-
5/25/2018 HASH TABLE
10/17
hashCode()
En un lenguaje orientado a objetos como es Java, la
primera fase de hash ing, la funcin hash1, esresponsabilidad de la clase de la clave, no de la clase de latabla hash.
La tabla hashalmacenar las entradas como Object. Notiene informacin suficiente para generar un cdigo hashdesde Object, que podra ser un String, un Integero unobjeto personalizado.
Java confirma esto mediante el mtodo hashCode() enObject. Todas las clases de Java amplan implcita oexplcitamente a Object. Y Object posee un mtodohashCode() que devuelve un int.
Cuidado: el mtodo hashCode() puede devolver un enteronegativo en Java; si queremos un entero no negativo (ysolemos quererlo) deberemos tomar el valor absoluto dehashCode().
19
Qu propiedades debetener un cdigo hash?
Como utilizamos cdigos hashpara indexar en la tablahashy encontrar objetos, el cdigo hashdel objeto debepermanecer fijo a lo largo del programa.
Un nmero realmente aleatorio no sera vlido para uncdigo hashaceptable, ya que generara un valor distintocada vez que disperssemos.
Si dos objetos son equivalentes (pero no necesariamente
idnticos), como dos copias de la misma cadena, loscdigos hashde los dos objetos tambin seran iguales, yaque deben recuperar el mismo objeto de la tabla hash.
Formalmente, si o1 y o2 son Object yo1.equals(o2), entonces o1.hashCode()debera ser== o2.hashCode().
Si ignora los mtodos equals() de una clase, probablementetambin debera ignorar el mtodo hashCode().
20
-
5/25/2018 HASH TABLE
11/17
Diseo del cdigo hash
El hashingtiene mucho ms de arte que deciencia, especialmente en el diseo defunciones hash1.
La ltima comprobacin de un buen cdigohashes ver si distribuye sus claves de un modoaleatorio correcto.
Se debe seguir algunos principios:
1. Un cdigo hashdebe depender tanto como sea
posible de la clave.
2. Un cdigohash
debera asumir que sufrirmanipulaciones posteriores para adaptarse al tamaoconcreto de la tabla: la fase hash2.
21
hashCode()de la claseString
La clase String de Java ignora Object() y debe ignorar,por tanto, hashCode().
La representacin interna de una cadena en Java esun arrayde caracteres:
// almacenamiento de caracteres
private char value[];
// offset es el ndice de la primera posicin utilizadaprivate int offset;
// count es el nmero de caracteres de la cadena
private int count;
// Almacena en cach el cdigo hash de la cadena
private int hash = 0;
22
-
5/25/2018 HASH TABLE
12/17
hashCode()de la claseString, 2
public int hashCode() {
int h = hash;
if (h == 0) {int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++)
h = 31*h + val[off++];
hash = h;
}
return h;}
23
La funcin hash2
Una vez que el mtodo hashCode() devuelve un int,todava nos queda distribuirlo (ste es el papel de hash2) en
uno de los m slots , h, 0h
-
5/25/2018 HASH TABLE
13/17
Hashingde enteros
Un buen mtodo para dispersar un entero (incluyendonuestros cdigos hash) es multiplicar el entero por unnmero A , 0
-
5/25/2018 HASH TABLE
14/17
Miembros de HashMap
public class HashMap
implements Map
{
private int length = 0;// encabezados de cadenas para slots
private Entry [] table = null;
private static final double golden =
(Math.sqrt(5.0) - 1.0)/2.0;
public static final int DEFAULT_SLOTS = 64;
public HashMap( int slots ) {table = new Entry[ slots ];clear();
}
27
Entrada de clase interna esttica
private static class Entry {final Object key;
Object value;
Entry next;
Entry( Object k, Object v, Entry n )
{ key = k; value = v; next = n; }
Entry( Object k, Object v )
{ key = k; value = v; next = null; }
Entry( Object k ){ key = k; value = null; next = null; }
}
28
-
5/25/2018 HASH TABLE
15/17
Mtodo clear()
public void clear()
{
length = 0;
for ( int i = 0; i < table.length; i++ )
table[ i ] = null;
}
29
Mtodoput()
public Object put( Object k, Object v )
{
if ( k == null )
throw new IllegalArgumentException(
"Clave null no permitida"
); int idx = index( k.hashCode() );Entry current = table[ idx ];
30
-
5/25/2018 HASH TABLE
16/17
Mtodoput(), 2
// Si la clave existe en el mapa, salir apuntando// hacia ella; si no valor actual == null
while ( current != null )
{
if ( current.key.equals( k ) )
break;
current = current.next;
}
31
Mtodoput(), 3
if ( current == null ) { // Lo encontramos?// No, insertar un nuevo elemento en encabezado de cadena
length++;
// Nuevo encabezado apunta al antiguo
table[ idx ] = new Entry( k, v, table[ idx ] );
return null;
} else { // S, lo encontramos// Reemplazar valor y devolver antiguo
Object ret = current.value; current.value =
v;
return ret;
}}
32
-
5/25/2018 HASH TABLE
17/17
Mtodo index()
// Volver a dispersar para garantizar buena distribucin
// h a s h
private int index( int hcode )
{
double t = Math.abs( hcode ) * GOLDEN;
return ((int) ((t - (int)t) * table.length ));
}
33
Mtodo get()
public Object get( Object k ) {
if ( k == null )
throw new IllegalArgumentException(
"Clave null no permitida" );
Entry current = table[ index( k.hashCode()) ];
// buscar coincidencia en este slot;// si el slot est vaco, devolver inmediatamente
while ( current != null ) {
if ( current.key.equals( k ) )
return current.value;
current = current.next;
}return null;
}
34