HASH TABLE

download HASH TABLE

of 17

description

TAB

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