Tabla hash en estructura de datos: Python Ejemplo
ยฟQuรฉ es Hashing?
Un hash es un valor que tiene una longitud fija y se genera mediante una fรณrmula matemรกtica. Los valores hash se utilizan en compresiรณn de datos, criptologรญa, etc. En la indexaciรณn de datos, los valores hash se utilizan porque tienen un tamaรฑo de longitud fijo independientemente de los valores que se utilizaron para generarlos. Hace que los valores hash ocupen un espacio mรญnimo en comparaciรณn con otros valores de diferentes longitudes.
Una funciรณn hash emplea un algoritmo matemรกtico para convertir la clave en un hash. Se produce una colisiรณn cuando una funciรณn hash produce el mismo valor hash para mรกs de una clave.
ยฟQuรฉ es una tabla hash?
A TABLA DE PICADILLO es una estructura de datos que almacena valores utilizando un par de claves y valores. A cada valor se le asigna una clave รบnica que se genera mediante una funciรณn hash.
El nombre de la clave se utiliza para acceder a su valor asociado. Esto hace que la bรบsqueda de valores en una tabla hash sea muy rรกpida, independientemente de la cantidad de elementos que contenga.
Funciones hash
Por ejemplo, si queremos almacenar registros de empleados y cada empleado se identifica de forma รบnica mediante un nรบmero de empleado.
Podemos utilizar el nรบmero de empleado como clave y asignar los datos del empleado como valor.
El enfoque anterior requerirรก espacio libre adicional del orden de (m * n2) donde la variable m es el tamaรฑo de la matriz, y la variable n es el nรบmero de dรญgitos del nรบmero de empleado. Este enfoque introduce un problema de espacio de almacenamiento.
Una funciรณn hash resuelve el problema anterior obteniendo el nรบmero de empleado y usรกndolo para generar un valor entero hash, dรญgitos fijos y optimizando el espacio de almacenamiento. El propรณsito de una funciรณn hash es crear una clave que se usarรก para hacer referencia al valor que queremos almacenar. La funciรณn acepta el valor que se guardarรก y luego utiliza un algoritmo para calcular el valor de la clave.
El siguiente es un ejemplo de una funciรณn hash simple
h(k) = k1 % m
AQUร,
- h(k) es la funciรณn hash que acepta un parรกmetro k. El parรกmetro k es el valor para el que queremos calcular la clave.
- k1 % m es el algoritmo para nuestra funciรณn hash, donde k1 es el valor que queremos almacenar y m es el tamaรฑo de la lista. Usamos el operador mรณdulo para calcular la clave.
Ejemplo
Supongamos que tenemos una lista con un tamaรฑo fijo de 3 y los siguientes valores
[ 1,2,3 ]
Podemos utilizar la fรณrmula anterior para calcular las posiciones que debe ocupar cada valor.
La siguiente imagen muestra los รญndices disponibles en nuestra tabla hash.
Paso 1) Calcula la posiciรณn que ocuparรก el primer valor asรญ.
h(1) = 1 % 3
= 1
El valor 1 ocuparรก el espacio en รndice 1
Paso 2) Calcular la posiciรณn que ocuparรก el segundo valor.
h(2) = 2 % 3
= 2
El valor 2 ocuparรก el espacio en รndice 2
Paso 3) Calcula la posiciรณn que ocuparรก el tercer valor.
h(3) = 3 % 3
= 0
El valor 3 ocuparรก el espacio en รndice 0
Resultado final de
Nuestra tabla hash completada ahora serรก la siguiente.
Cualidades de una buena funciรณn hash
Una buena funciรณn hash debe tener las siguientes cualidades.
- La fรณrmula para generar el hash debe utilizar el valor de los datos que se almacenarรกn en el algoritmo.
- La funciรณn hash debe generar valores hash รบnicos incluso para datos de entrada que tengan la misma cantidad.
- La funciรณn debe minimizar el nรบmero de colisiones. Las colisiones ocurren cuando se genera el mismo valor para mรกs de un valor.
- Los valores deben distribuirse de forma coherente entre todos los hashes posibles.
Colisiรณn
Se produce una colisiรณn cuando el algoritmo genera el mismo hash para mรกs de un valor.
Veamos un ejemplo.
Supongamos que tenemos la siguiente lista de valores
[ 3,2,9,11,7 ]
Supongamos que el tamaรฑo de la tabla hash es 7 y usaremos la fรณrmula (k1 % m) donde m es el tamaรฑo de la tabla hash.
La siguiente tabla muestra los valores hash que se generarรกn.
| Clave | Algoritmo hash (k1 % m) | Valor hash |
|---|---|---|
| 3 | 3% 7 | 3 |
| 2 | 3% 7 | 2 |
| 9 | 3% 7 | 2 |
| 11 | 3% 7 | 4 |
| 7 | 3% 7 | 0 |
Como podemos ver en los resultados anteriores, los valores 2 y 9 tienen el mismo valor hash y no podemos almacenar mรกs de un valor en cada posiciรณn.
El problema planteado se puede resolver mediante encadenamiento o sondeo. En las siguientes secciones se analizan en detalle el encadenamiento y el sondeo.
Encadenamiento
El encadenamiento es una tรฉcnica que se utiliza para resolver el problema de colisiรณn mediante el uso de listas enlazadas, cada una de las cuales tiene รญndices รบnicos.
La siguiente imagen visualiza cรณmo se ve una lista encadenada
Tanto el 2 como el 9 ocupan el mismo รญndice, pero se almacenan como listas enlazadas. Cada lista tiene un identificador รบnico.
Beneficios de las listas encadenadas
Los siguientes son los beneficios de las listas encadenadas:
- Las listas encadenadas tienen un mejor rendimiento al insertar datos porque el orden de inserciรณn es O(1).
- No es necesario cambiar el tamaรฑo de una tabla hash que utiliza una lista encadenada.
- Puede acomodar fรกcilmente una gran cantidad de valores siempre que haya espacio libre disponible.
Sondeo
La otra tรฉcnica que se utiliza para resolver colisiones es el sondeo. Cuando utilizamos el mรฉtodo de sondeo, si ocurre una colisiรณn, simplemente podemos seguir adelante y encontrar una ranura vacรญa para almacenar nuestro valor.
Los siguientes son los mรฉtodos de sondeo:
| Mรฉtodo | Descripciรณn |
|---|---|
| Palpado lineal | Tal como sugiere el nombre, este mรฉtodo busca ranuras vacรญas linealmente comenzando desde la posiciรณn donde ocurriรณ la colisiรณn y avanzando. Si se llega al final de la lista y no se encuentra ningรบn espacio vacรญo. El sondeo comienza al principio de la lista. |
| Sondeo cuadrรกtico | Este mรฉtodo utiliza expresiones polinรณmicas cuadrรกticas para encontrar el siguiente espacio libre disponible. |
| Double Hashing | Esta tรฉcnica utiliza un algoritmo de funciรณn hash secundaria para encontrar la siguiente ranura libre disponible. |
Usando nuestro ejemplo anterior, la tabla hash despuรฉs de usar el sondeo aparecerรญa de la siguiente manera:
Operaciones de tabla hash
Aquรญ estรกn los Operaciones soportadas por tablas Hash:
- Inserciรณn - Este OperaLa ciรณn se utiliza para agregar un elemento a la tabla hash.
- Bรบsqueda - Este Operaciรณn se utiliza para buscar elementos en la tabla hash usando la clave
- Eliminaciรณn - Este OperaLa ciรณn se utiliza para eliminar elementos de la tabla hash.
Operaciรณn de inserciรณn de datos
La operaciรณn de inserciรณn se utiliza para almacenar valores en la tabla hash. Cuando se almacena un nuevo valor en la tabla hash, se le asigna un nรบmero de รญndice. El nรบmero de รญndice se calcula mediante la funciรณn hash. La funciรณn hash resuelve cualquier colisiรณn que se produzca al calcular el nรบmero de รญndice.
Bรบsqueda de operaciones de datos
La operaciรณn de bรบsqueda se utiliza para buscar valores en la tabla hash utilizando el nรบmero de รญndice. La operaciรณn de bรบsqueda devuelve el valor vinculado al nรบmero de รญndice de bรบsqueda. Por ejemplo, si almacenamos el valor 6 en el รญndice 2, la operaciรณn de bรบsqueda con el nรบmero de รญndice 2 devolverรก el valor 6.
Operaciรณn de eliminaciรณn de datos
La operaciรณn de eliminaciรณn se utiliza para eliminar un valor de una tabla hash. Para eliminar el valor OperaLa eliminaciรณn se realiza mediante el nรบmero de รญndice. Una vez que se ha eliminado un valor, el nรบmero de รญndice queda libre. Se puede utilizar para almacenar otros valores mediante la operaciรณn de inserciรณn.
Implementaciรณn de tabla hash con Python Ejemplo
Veamos un ejemplo simple que calcula el valor hash de una clave.
def hash_key( key, m):
return key % m
m = 7
print(f'The hash value for 3 is {hash_key(3,m)}')
print(f'The hash value for 2 is {hash_key(2,m)}')
print(f'The hash value for 9 is {hash_key(9,m)}')
print(f'The hash value for 11 is {hash_key(11,m)}')
print(f'The hash value for 7 is {hash_key(7,m)}')
Explicaciรณn del cรณdigo de la tabla hash
AQUร,
- Define una funciรณn hash_key que acepta los parรกmetros clave y m.
- Utiliza una operaciรณn de mรณdulo simple para determinar el valor hash
- Define una variable m que se inicializa con el valor 7. Este es el tamaรฑo de nuestra tabla hash.
- Calcula e imprime el valor hash de 3
- Calcula e imprime el valor hash de 2
- Calcula e imprime el valor hash de 9
- Calcula e imprime el valor hash de 11
- Calcula e imprime el valor hash de 7
La ejecuciรณn del cรณdigo anterior produce los siguientes resultados.
The hash value for 3 is 3 The hash value for 2 is 2 The hash value for 9 is 2 The hash value for 11 is 4 The hash value for 7 is 0
Python Ejemplo de diccionario
Python viene con un tipo de datos incorporado llamado Diccionario. Un diccionario es un ejemplo de tabla hash. Almacena valores utilizando un par de claves y valores. Los valores hash se generan automรกticamente y cualquier colisiรณn se resuelve en segundo plano.
El siguiente ejemplo muestra cรณmo se puede utilizar un tipo de datos de diccionario en python 3
employee = {
'name': 'John Doe',
'age': 36,
'position': 'Business Manager.'
}
print (f"The name of the employee is {employee['name']}")
employee['position'] = 'Software Engineer'
print (f"The position of {employee['name']} is {employee['position']}")
employee.clear()
print (employee)
AQUร,
- Define una variable de diccionario empleado. El nombre de clave se utiliza para almacenar el valor John Doe, la edad almacena 36 y la posiciรณn almacena el valor Business Manager.
- Recupera el valor del nombre de la clave y lo imprime en la terminal.
- Actualiza el valor de la posiciรณn clave al valor Ingeniero de software
- Imprime los valores del nombre y posiciรณn de las claves.
- Elimina todos los valores que estรกn almacenados en nuestro diccionario variable empleado
- Imprime el valor del empleado.
La ejecuciรณn del cรณdigo anterior produce los siguientes resultados.
The name of the employee is John Doe.
The position of John Doe is a Software Engineer.
{}
Anรกlisis de complejidad
Las tablas hash tienen una complejidad temporal promedio de O (1) en el mejor de los casos. La complejidad temporal en el peor de los casos es O(n). El peor de los casos ocurre cuando muchos valores generan la misma clave hash y tenemos que resolver la colisiรณn mediante un sondeo.
Aplicaciones del mundo real
En el mundo real, las tablas hash se utilizan para almacenar datos para
- Bases de datos
- Matrices asociativas
- Sets
- Memoria cachรฉ
Ventajas de las tablas hash
A continuaciรณn se detallan las ventajas y ventajas de utilizar tablas hash:
- Las tablas hash tienen un alto rendimiento al buscar datos, insertar y eliminar valores existentes.
- La complejidad temporal de las tablas hash es constante independientemente del nรบmero de elementos de la tabla.
- Funcionan muy bien incluso cuando trabajan con grandes conjuntos de datos.
Desventajas de las tablas hash
Estas son las desventajas de usar tablas hash:
- No puede utilizar un valor nulo como clave.
- No se pueden evitar colisiones al generar claves utilizando. funciones hash. Las colisiones ocurren cuando se genera una clave que ya estรก en uso.
- Si la funciรณn hash tiene muchas colisiones, esto puede provocar una disminuciรณn del rendimiento.
Resumen
- Las tablas hash se utilizan para almacenar datos utilizando un par de claves y valores.
- Una funciรณn hash utiliza un algoritmo matemรกtico para calcular el valor hash.
- Se produce una colisiรณn cuando se genera el mismo valor hash para mรกs de un valor.
- El encadenamiento resuelve la colisiรณn mediante la creaciรณn de listas vinculadas.
- El sondeo resuelve la colisiรณn al encontrar espacios vacรญos en la tabla hash.
- El sondeo lineal busca la siguiente ranura libre para almacenar el valor a partir de la ranura donde ocurriรณ la colisiรณn.
- El sondeo cuadrรกtico utiliza expresiones polinรณmicas para encontrar el siguiente espacio libre cuando ocurre una colisiรณn.
- Double El hashing utiliza un algoritmo de funciรณn hash secundaria para encontrar la siguiente ranura libre cuando ocurre una colisiรณn.
- Las tablas hash tienen un mejor rendimiento en comparaciรณn con otras estructuras de datos.
- La complejidad temporal promedio de las tablas hash es O (1)
- Un tipo de datos de diccionario en Python es un ejemplo de tabla hash.
- Las tablas hash admiten operaciones de inserciรณn, bรบsqueda y eliminaciรณn.
- Un valor nulo no se puede utilizar como valor de รญndice.
- Las colisiones no se pueden evitar en las funciones hash. Una buena funciรณn hash minimiza la cantidad de colisiones que ocurren para mejorar el rendimiento.






