You are on page 1of 8

Mtodo de bsqueda POR FUNCIONES DE HASH

Bsqueda mediante transformacin de claves (hashing) Es un mtodo de bsqueda que aumenta la velocidad de bsqueda, pero que no requiere que los elementos estn ordenados. Consiste en asignar a cada elemento un ndice mediante una transformacin del elemento. Esta correspondencia se realiza mediante una funcin de conversin, llamada funcin hash. La correspondencia ms sencilla es la identidad, esto es, al nmero 0 se le asigna el ndice 0, al elemento 1 el ndice 1, y as sucesivamente. Pero si los nmeros a almacenar son demasiado grandes esta funcin es inservible. Por ejemplo, se quiere guardar en un array la informacin de los 1000 usuarios de una empresa, y se elige el nemro de DNI como elemento identificativo. Es inviable hacer un array de 100.000.000 elementos, sobre todo porque se desaprovecha demasiado espacio. Por eso, se realiza una transformacin al nmero de DNI para que nos de un nmero menor, por ejemplo coger las 3 ltimas cifras para guardar a los empleados en un array de 1000 elementos. Para buscar a uno de ellos, bastara con realizar la transformacin a su DNI y ver si est o no en el array. La funcin de hash ideal debera ser biyectiva, esto es, que a cada elemento le corresponda un ndice, y que a cada ndice le corresponda un elemento, pero no siempre es fcil encontrar esa funcin, e incluso a veces es intil, ya que puedes no saber el nmero de elementos a almacenar. La funcin de hash depende de cada problema y de cada finalidad, y se pueden utilizar con nmeros o cadenas, pero las ms utilizadas son:

Restas sucesivas: esta funcin se emplea con claves numricas entre las que existen huecos de tamao conocido, obtenindose direcciones consecutivas. Por ejemplo, si el nmero de expediente de un alumno universitario est formado por el ao de entrada en la universidad, seguido de un nmero identificativo de tres cifras, y suponiendo que entran un mximo de 400 alumnos al ao, se le asignaran las claves:1998-000 --> 0 = 1998000-1998000 1998-001 --> 1 = 1998001-1998000 1998-002 --> 2 = 1998002-1998000 ... 1998-399 --> 399 = 1998399-1998000 1999-000 --> 400 = 1999000-1998000+400 ... yyyy-nnn --> N = yyyynnn-1998000+(400*(yyyy-1998)) Aritmtica modular: el ndice de un nmero es resto de la divisin de ese nmero entre un nmero N prefijado, preferentemente primo. Los nmeros se guardarn en las direcciones de memoria de 0 a N-1. Este mtodo tiene el problema de que cuando hay N+1 elementos, al menos

un ndice es sealado por dos elementos (teorema del palomar). A este fenmeno se le llama colisin, y es tratado ms adelante. Si el nmero N es el 13, los nmeros siguientes quedan transformados en:13000000 --> 0 12345678 --> 7 13602499 --> 1 71140205 --> 6 73062138 --> 6 Mitad del cuadrado: consiste en elevar al cuadrado la clave y coger las cifras centrales. Este mtodo tambin presenta problemas de colisin:123*123=15129 --> 51 136*136=18496 --> 84 730*730=532900 --> 29 301*301=90601 --> 06 625*625=390625 --> 06 Truncamiento: consiste en ignorar parte del nmero y utilizar los elementos restantes como ndice. Tambin se produce colisin. Por ejemplo, si un nmero de 8 cifras se debe ordenar en un array de 1000 elementos, se pueden coger la primer, la tercer y la ltima cifras para formar un nuevo nmero:13000000 --> 100 12345678 --> 138 13602499 --> 169 71140205 --> 715 73162135 --> 715 Plegamiento: consiste en dividir el nmero en diferentes partes, y operar con ellas (normalmente con suma o multiplicacin). Tambin se produce colisin. Por ejemplo, si dividimos los nmero de 8 cifras en 3, 3 y 2 cifras y se suman, dar otro nmero de tres cifras (y si no, se cogen las tres ltimas cifras):13000000 --> 130=130+000+00 12345678 --> 657=123+456+78 71140205 --> 118 --> 1118=711+402+05 13602499 --> 259=136+024+99 25000009 --> 259=250+000+09

Tratamiento de colisiones:

Pero ahora se nos presenta el problema de qu hacer con las colisiones, qu pasa cuando a dos elementos diferentes les corresponde el mismo ndice. Pues bien, hay tres posibles soluciones: Cuando el ndice correspondiente a un elemento ya est ocupada, se le asigna el primer ndice libre a partir de esa posicin. Este mtodo es poco eficaz, porque al nuevo elemento se le asigna un ndice que podr estar ocupado por un elemento posterior a l, y la bsqueda se ralentiza, ya que no se sabe la posicin exacta del elemento. Tambin se pueden reservar unos cuantos lugares al final del array para alojar a las colisiones. Este mtodo tambin tiene un problema: Cunto espacio se debe reservar? Adems, sigue la lentitud de bsqueda si el elemento a buscar es una colisin. Lo ms efectivo es, en vez de crear un array de nmero, crear un array de punteros, donde cada puntero seala el principio de una lista enlazada. As, cada elemento que llega a un determinado ndice se pone en el ltimo lugar de la lista de ese ndice. El tiempo de bsqueda se reduce considerablemente, y no hace falta poner restricciones al tamao del array, ya que se pueden aadir nodos dinmicamente a la lista... "LAS TABLAS HASH" En una "tabla hash", los elementos estn formados por una pareja: una clave y un valor, como en un SortedList, pero la diferencia est en la forma en que se manejan internamente estos datos: la "tabla hash" usa una "funcin de dispersin" para colocar los elementos, de forma que no se pueden recorrer secuencialmente, pero a cambio el acceso a partir de la clave es muy rpido, ms que si hacemos una bsqueda secuencial (como en un array) o binaria (como en un ArrayList ordenado). Un ejemplo de diccionario, parecido al anterior (que es ms rpido de consultar para un dato concreto, pero que no se puede recorrer en orden), podra ser: /*---------------------------*/ /* Ejemplo en C# */ /* HashTable1.cs */ /* */ /* Ejemplo de HashTable: */ /* Diccionario de inform. */ /* */ /* Introduccion a C#, */ /* Nacho Cabanes */ /*---------------------------*/ using System; using System.Collections; public class ejemploHashTable { public static void Main() { Creamos e insertamos datos Hashtable miDiccio = new Hashtable(); miDiccio.Add("byte", "8 bits"); miDiccio.Add("pc", "personal computer"); miDiccio.Add("kilobyte", "1024 bytes");

Mostramos algn dato Console.WriteLine( "Cantidad de palabras en el diccionario: {0}", miDiccio.Count ); try { Console.WriteLine( "El significado de PC es: {0}", miDiccio["pc"]); } catch (Exception e) { Console.WriteLine( "No existe esa palabra!"); } } } que escribira en pantalla: Cantidad de palabras en el diccionario: 3 El significado de PC es: personal computer Si un elemento que se busca no existe, se lanzara una excepcin, por lo que deberamos controlarlo con un bloque try..catch. Lo mismo ocurre si intentamos introducir un dato que ya existe. Una alternativa a usar try..catch es comprobar si el dato ya existe, con el mtodo "Contains" (o su sinnimo "ContainsKey"), como en este ejemplo: /*---------------------------*/ /* Ejemplo en C# */ /* HashTable2.cs */ /* */ /* Ejemplo de HashTable 2: */ /* Diccionario de inform. */ /* */ /* Introduccion a C#, */ /* Nacho Cabanes */ /*---------------------------*/ using System; using System.Collections; public class ejemploHashTable2 { public static void Main() { Creamos e insertamos datos Hashtable miDiccio = new Hashtable(); miDiccio.Add("byte", "8 bits"); miDiccio.Add("pc", "personal computer"); miDiccio.Add("kilobyte", "1024 bytes"); Mostramos algn dato Console.WriteLine( "Cantidad de palabras en el diccionario: {0}",

miDiccio.Count ); if (miDiccio.Contains("pc")) Console.WriteLine( "El significado de PC es: {0}", miDiccio["pc"]); else Console.WriteLine( "No existe la palabra PC"); } } Otras posibilidades son: borrar un elemento ("Remove"), vaciar toda la tabla ("Clear"), o ver si contiene un cierto valor ("ContainsValue", mucho ms lento que buscar entre las claves con "Contains"). Una tabla hash tiene una cierta capacidad inicial, que se ampla automticamente cuando es necesario. Como la tabla hash es mucho ms rpida cuando est bastante vaca que cuando est casi llena, podemos usar un constructor alternativo, en el que se le indica la capacidad inicial que queremos, si tenemos una idea aproximada de cuntos datos vamos a guardar: Hashtable miDiccio = new Hashtable(500); Una tabla Hash es una tabla donde tienes clave, y valor. El cdigo hash es nico para cada valor y cada valor slo tiene un cdigo hash. Ejemplo de una taba hash: clave 1 : valor"Nombre" clave 2 : valor"Apellido" entonces si tu quieres buscar el nombre, consultas en la tabla por su clave. Ejemplo en java Hashtable ht = new Hashtable(); ht.put("clave1", "Nombre"); ht.put("clave2", "Apellido"); System.out.println(ht.get("clave1"))

import java.util.*; public class hash { public static void main (String args[]) throws Exception {

Hashtable hash = new Hashtable(10,10); for (int i = 0; i <= 100; i++)

{ Integer entero = new Integer ( i ); hash.put( entero, "Numero : " + i); } for (Enumeration e = hash.keys(); e.hasMoreElements();) { System.out.println (hash.get(e.nextElement())); } } }

Una tabla hash no es mas que una estructura de datos para asociar valores con llaves. Imaginate algo asi LLave => Valor Carlos => Mexico Jose => China Juan => USA Ernesto => Peru Ahi estariamos relacionando un grupo de nombres con su pais de origen.En java la implementacion seria con la clase Hashtable, aunque mas recientemente se ha favorecido el uso de Hashmap que es muy similar pero con pequeas diferencias.Esta es una implementacion de una hashtable en java, no hace nada en especial... solo relaciona numeros con mas numeros de forma automtica.

VENTAJAS E INCONVENIENTES DE LAS TABLAS HASH

Una tabla hash tiene como principal ventaja que el acceso a los datos suele ser muy rpido si se cumplen las siguientes condiciones:

Una razn de ocupacin no muy elevada (a partir del 75% de ocupacin se producen demasiadas colisiones y la tabla se vuelve ineficiente). Una funcin resumen que distribuya uniformemente las claves. Si la funcin est mal diseada, se producirn muchas colisiones.

Los inconvenientes de las tablas hash son: --->Necesidad de ampliar el espacio de la tabla si el volumen de datos almacenados crece. Se trata de una operacin costosa. --->Dificultad para recorrer todos los elementos. Se suelen emplear listas para procesar la totalidad de los elementos. --->Desaprovechamiento de la memoria. Si se reserva espacio para todos los posibles elementos, se consume ms memoria de la necesaria; se suele resolver reservando espacio nicamente para punteros a los elementos. INSERCIN

Para almacenar un elemento en la tabla hash se ha de convertir su clave a un nmero. Esto se consigue aplicando la funcin resumen a la clave del elemento. El resultado de la funcin resumen ha de mapearse al espacio de direcciones del array que se emplea como soporte, lo cual se consigue con la funcin mdulo. Tras este paso se obtiene un ndice vlido para la tabla. El elemento se almacena en la posicin de la tabla obtenido en el paso anterior. Si en la posicin de la tabla ya haba otro elemento, se ha producido una colisin. Este problema se puede solucionar asociando una lista a cada posicin de la tabla, aplicando otra funcin o buscando el siguiente elemento libre. Estas posibilidades han de considerarse a la hora de recuperar los datos.

Las tablas hash se suelen implementar sobre arrays de una dimensin, aunque se pueden hacer implementaciones multi-dimensionales basadas en varias claves. Como en el caso de los arrays, las tablas hash proveen tiempo constante de bsqueda promedio O(1),[1] sin importar el nmero de elementos en la tabla. Sin embargo, en casos particularmente malos el tiempo de bsqueda puede llegar a O(n), es decir, en funcin del nmero de elementos.

Comparada con otras estructuras de arrays asociadas, las tablas hash son ms tiles cuando se almacenan grandes cantidades de informacin.

Las tablas hash almacenan la informacin en posiciones pseudo-aleatorias, as que el acceso ordenado a su contenido es bastante lento. Otras estructuras como rboles binarios autobalanceables son ms rpidos en promedio (tiempo de bsqueda O(log n)) pero la informacin est ordenada en todo momento.

TABLAS HASH Una tabla hash o mapa hash es una estructura de datos que asocia llaves o claves con valores. La operacin principal que soporta de manera eficiente es la bsqueda: permite el acceso a los elementos (telfono y direccin, por ejemplo) almacenados a partir de una clave generada (usando el nombre o nmero de cuenta, por ejemplo). Funciona transformando la clave con una funcin hash en un hash, un nmero que la tabla hash utiliza para localizar el valor deseado.

QUE ES UNA FUNCIN DE HASH

Es una funcin para resumir o identificar probabilsticamente un gran conjunto de informacin, dando como resultado un conjunto imagen finito generalmente menor (un subconjunto de los nmeros naturales por ejemplo). Varan en los conjuntos de partida y de llegada y en cmo afectan a la salida similitudes o patrones de la entrada. Una propiedad fundamental del hashing es que si dos resultados de una misma funcin son diferentes, entonces las dos entradas que generaron dichos resultados tambin lo son. Es posible que existan claves resultantes iguales para objetos diferentes, ya que el rango de posibles claves es mucho menor que el de posibles objetos a resumir (las claves suelen tener en torno al centenar de bits, pero los ficheros no tienen un tamao lmite). Son usadas en mltiples aplicaciones, como los arrays asociativos, criptografa, procesamiento de datos y firmas digitales, entre otros. Una buena funcin de hash es una que experimenta pocas colisiones en el conjunto esperado de entrada; es decir que se podrn identificar unvocamente las entradas (ver funcin inyectiva). Muchos sistemas relacionados con la seguridad informtica usan funciones o tablas hash.