Está en la página 1de 61

TIPOS DE DATOS

AVANZADOS II:
TABLAS
(MAPAS/DICCIONARIOS)
Tema 5
1. Fundamentos.
Tema 4. 2. Representación.
3. Representación mediante C++/STL.
Tablas 4. Aplicaciones.

2
Definición

■ Llamamos Tabla a una función que asocia los elementos de un


conjunto (dominio) con los elementos de otro conjunto (imagen).
– Es una función parcial porque no todos los elementos del
dominio tienen porque estar asociados con un valor imagen.
– Conjunto dominio = Clave
– Conjunto imagen = Valor

Clave Valor

t: Clave  Valor
t es una Tabla

Estructuras de datos y algoritmos (TEMA 5) 3


Ejemplo de Tabla: Vector

■ Tabla es un concepto general en el que no se plantea ninguna


restricción sobre el conjunto de claves.
■ Llamamos Vector (array) a una especialización de la tabla donde
las claves (índices) son una secuencia de enteros o un tipo
enumerado. Habrá por tanto una clave (índice) máxima y mínima.

– Ejemplo:

Estructuras de datos y algoritmos (TEMA 5) 4


TAD Tabla. Operaciones
Tipo Tabla
Dominio:
Tipo Tabla definido sobre los tipos Clave y Valor
𝔹𝔹: 𝑡𝑡𝑡𝑡𝑡𝑡𝑡𝑡 𝑏𝑏𝑏𝑏𝑏𝑏𝑏𝑏𝑏𝑏𝑏𝑏𝑏𝑏

Operaciones:

t_nula: → Tabla
asignar: Tabla, Clave, Valor → Tabla
consultar: Tabla, Clave → Valor Puede implicar Buscar
definida: Tabla, Clave → 𝔹𝔹

Estructuras de datos y algoritmos (TEMA 5) 5


Ejemplos (conocidos) de tablas

■ Array:
float v[100];
– Clave = 0..99
– Valor = float
■ vector:
#include <vector>
vector<float> v;
– Clave = unsigned int
– Valor = float
■ Árboles Binarios de Búsqueda: C++
#include <map>
– ABB a; map<TipoClave,TipoInfo> a;
– Clave = ABB::TipoClave
Árboles Rojo-Negro (Red-Black Trees)
– Valor = ABB::TipoInfo ABB + criterio de autoequilibrio

Estructuras de datos y algoritmos (TEMA 5) 6


Tablas: Revisión del planteamiento general

■ Una tabla es un ADT que asocia 1 Clave con 1 Valor.


■ Situación ideal: Implementar mediante un array (vector), donde cada
clave que pueda aparecer tenga asociada una posición (índice) del array
 la operación búsqueda/inserción tendría un coste O(1) (acceso
directo mediante el índice asociado a la clave).
■ Situación real: Espacio de claves muy grande  no es factible definir un
array con posiciones reservadas para cada posible clave de búsqueda
(tantos índices del array como posibles claves).
■ Ejemplo:
– Sistema de registro de usuarios en un servicio de vídeo online.
– Claves = Nombres de usuario.
– ¿Cuántas posibles claves se pueden crear?
– ¿Es factible definir un array con tantos índices como posibles
nombres de usuario se puedan crear (se usen o no)?
■ solo letras (27) + máximo 16 char = 7,97664E+22 claves

Estructuras de datos y algoritmos (TEMA 5) 7


Tablas Hash

■ Idea general: Transformar las claves en índices de un array


(vector), de manera que:
– La misma clave siempre se transforme en el mismo índice.
– En la posición del array identificada por el índice se encuentre
el valor asociado con la clave original.

C V
x 0
x x

x xx
k p = f(k)
x
x

x
x
x x
x
p v[p] = valor
x
x x
x
x
x


asociado con k
x x
x x
x
x x
x m-1

Estructuras de datos y algoritmos (TEMA 5) 8


Tablas Hash: Problemas a resolver

■ Seleccionar una función de transformación, que


distribuya las claves sobre las posiciones del vector
(índices).
– Función de hashing

■ Hay muchos menos índices que posibles claves 


múltiples claves se transformarán en un mismo
índice.
– ¿Qué pasa si f(k1)=f(k2)=p?
– ¿Qué hay en v[p]? ¿El valor asociado con k1, con
k2, o ambos?
– Tratamiento para las colisiones.

Estructuras de datos y algoritmos (TEMA 5) 9


Dispersión uniforme de claves

C V
x 0
x x
f(c) .
x xx
x
x
x
NO
.
x x x
x
x x

.
x x x
x
x x
x x
x
x x
x m-1

V
C x 0
x x
g(c) .
x
x x
x x

x
x
x
x
x x
x . SI
.
x x x
x x
x
x x
x
x x
x m-1

Estructuras de datos y algoritmos (TEMA 5) 10


Función de Hashing (1)

■ En general, las claves de búsqueda son alfanuméricas.


■ Hay que transformar claves alfanuméricas en índices numéricos.
■ Como los caracteres de la clave se representan internamente
como valores numéricos (enteros sin signo), podemos definir:

𝑓𝑓1 𝑐𝑐 = � 𝑐𝑐𝑖𝑖 % 𝑚𝑚
∀𝑐𝑐𝑖𝑖 ∈𝑐𝑐

siendo m el tamaño del vector/tabla (número máximo de


índices)

NOTA: Se aconseja siempre que m sea primo.

Estructuras de datos y algoritmos (TEMA 5) 11


Características de 𝑓𝑓1

𝑓𝑓1 𝑐𝑐 = � 𝑐𝑐𝑖𝑖 % 𝑚𝑚
∀𝑐𝑐𝑖𝑖 ∈𝑐𝑐

■ Insensible al orden de los caracteres en la clave:


𝑓𝑓1 "𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎 = 𝑓𝑓1 "𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟" = 𝑓𝑓1 "𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚" = 431
■ Genera “pocos” valores diferentes. Ejemplo:
– Claves alfanuméricas (‘a’..’z’, ‘A’..’Z’, ‘0’..’9’), máx. longitud 16.
– Claves diferentes = 6216 = 4,76724E+28
– Considerando que:
■ ‘0’..’9’  48..57
■ ‘A’..’Z’  65..90
■ ‘a’..’z’  97..122
– 𝑓𝑓1 (c) genera valores en el rango [48..1952] = 1905 valores.
– No sirve de nada incrementar el valor de m>1952.

Estructuras de datos y algoritmos (TEMA 5) 12


Función de Hashing (2)

■ Asociar un peso a la posición de cada carácter en la clave.


𝑓𝑓2 𝑐𝑐 = � 𝑐𝑐𝑖𝑖 . 𝑝𝑝𝑖𝑖 %m
∀𝑐𝑐𝑖𝑖 ∈𝑐𝑐
𝑝𝑝 es el peso asociado a la posición dentro de la clave
■ Se incrementa el coste del cálculo de la función:
– Multiplicaciones en el sumatorio.
– Las potencias del peso están precalculados.
■ Estrategias para reducir el coste computacional de 𝑓𝑓2 :
– Usar como peso una potencia de 2  las multiplicaciones se
traducen en desplazamientos de bits.
– Si la longitud de las claves es grande  seleccionar un
conjunto limitado de caracteres sobre los que aplicar hashing.

Estructuras de datos y algoritmos (TEMA 5) 13


Ejemplo 𝑓𝑓2

■ Considerar 𝑝𝑝 = 32 (=25):
𝑓𝑓2 𝑐𝑐 = � 𝑐𝑐𝑖𝑖 . 32𝑖𝑖 %m
∀𝑐𝑐𝑖𝑖 ∈𝑐𝑐
 peso asociado a cada posición de la clave = 320, 321, 322, 323, …
■ Calcular x*32 = desplazar 5 bits a la izquierda el valor x.
– Calcular x* 322 = desplazar 10 bits a la izquierda el valor x.
– Calcular x* 323 = desplazar 15 bits a la izquierda el valor x.
– …
■ El orden de los caracteres en la clave es importante:
𝑓𝑓2 "𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎 = 3.608.367 ≠ 𝑓𝑓2 "𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟 = 4.221.391
≠ 𝑓𝑓2 "𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚 = 4.041.871
■ Claves alfanuméricas (‘a’..’z’, ‘A’..’Z’, ‘0’..’9’), máx. longitud 16.
– 𝑓𝑓2 (c) genera valores en el rango [48.. 4,75771E+24]

Estructuras de datos y algoritmos (TEMA 5) 14


Implementación C++
size_t hash_1 (string clave, size_t m)
{
size_t suma=0;
for (size_t i = 0; i < clave.length(); i++)
suma += clave[i];
return suma%m;
}

size_t hash_2 (string clave , size_t m)


{
size_t suma = 0;
for (size_t i = 0; i < clave.length(); i++)
suma = (suma << 5) + clave[i];
return suma%m;
}

Estructuras de datos y algoritmos (TEMA 5) 15


Otros uso de las funciones de hashing

■ Criptografía y Seguridad:
– Una función de hashing transforma un valor arbitrario dentro
de un conjunto de elementos en un valor numérico de
longitud fija.
– A partir del valor numérico obtenido NO es posible revertir el
proceso (obtener el valor original que lo ha generado).
■ Ejemplo: Aplicar función de hash sobre todo un fichero de texto.
– La clave a transformar es todo el fichero (!!!).
– Se obtiene como resultado un valor numérico, que se puede
usar como “resumen” (huella) del documento.
– El valor hash del documento se puede distribuir de forma
segura porque no permite recuperar el documento original.
– El valor hash permite comparar y asegurar la veracidad de un
documento.
■ SHA-3, última versión del estándar Secure Hash Algorithm.

Estructuras de datos y algoritmos (TEMA 5) 16


Tratamiento de Colisiones

■ Colisión ≡ Múltiples claves se transforman (hash) en el mismo


índice.
■ Estrategias para tratar las colisiones:
– Encadenamiento: Cada posición del array (índice) mantiene
una estructura que almacena los valores de todas las claves
transformadas en ese índice. Típicamente una Lista enlazada.
– Dispersión cerrada: En una posición del array solo “cabe” un
valor  si una posición del array ya está ocupada se debe
buscar otra posición que esté libre:
■ Prueba lineal: buscar posiciones libres a intervalos fijos
(normalmente +1).
■ Prueba cuadrática: buscar posiciones libres a intervalos dados por
una función cuadrática.
■ Doble hashing: Utilizar una segunda función de hash (diferente) para
calcular los intervalos de búsqueda.

Estructuras de datos y algoritmos (TEMA 5) 17


Encadenamiento

■ Cada posición del array mantiene una lista de (Clave, Valor) con
los elementos que colisionan en esa posición.
■ Para localizar un valor hay que acceder a la posición del array y
buscar secuencialmente la clave en la lista correspondiente.

Estructuras de datos y algoritmos (TEMA 5) 18


Encadenamiento: Ejemplo

Insertar {89, 18, 49, 58, 69}

0
1
2
3

f ( c ) = c % 10 4
5
Insertar (89, “A”)
9 6
7
8 clave valor

9 89 A

Estructuras de datos y algoritmos (TEMA 5) 19


Encadenamiento: Ejemplo

Insertar {89, 18, 49, 58, 69}

0
1
2
3

f ( c ) = c % 10 4
5
Insertar (18, “B”)
8 6
7 clave valor

8 18 B

9 89 A

Estructuras de datos y algoritmos (TEMA 5) 20


Encadenamiento: Ejemplo

Insertar {89, 18, 49, 58, 69}

0
1
2
3

f ( c ) = c % 10 4
5
Insertar (49, “C”)
6
9
7
8 18 B

9 49 C 89 A

Estructuras de datos y algoritmos (TEMA 5) 21


Encadenamiento: Ejemplo

Insertar {89, 18, 49, 58, 69}

0
1
2
3

f ( c ) = c % 10 4

Insertar (58, “D”) 5

8 6
7
8 58 D 18 B

9 49 C 89 A

Estructuras de datos y algoritmos (TEMA 5) 22


Encadenamiento: Ejemplo

Insertar {89, 18, 49, 58, 69}

0
1
2
3

f ( c ) = c % 10 4
5

9 6
Insertar (69, “E”)
7
8 58 D 18 B

9 69 E 49 C 89 A

Estructuras de datos y algoritmos (TEMA 5) 23


Encadenamiento: Coste Buscar/Insertar

■ Insertar  O(1) ≡ Hashing + Insertar al inicio de la lista.


■ Buscar, tiene casos:
– Mejor caso: No hay colisiones. Todas las listas tienen 0 o 1
elemento  O(1).
– Peor caso: Todas las claves colisionan en la misma posición
 O(n), siendo n el número de claves almacenadas en la
tabla.
– Caso medio: el coste esperado dependerá del tamaño medio
de las listas generadas en la tabla  depende de si la función
de hashing realiza un “reparto” uniforme de claves o no.
– Factor de carga de la tabla, λ = n/m (claves almacenadas/nº
de posiciones en la tabla) ≡ tamaño medio de las listas.
■ En general, el coste de Buscar es O(λ)

Estructuras de datos y algoritmos (TEMA 5) 24


Dispersión cerrada

■ Cada posición de la tabla admite un único par (clave, dato).


■ Cuando la posición que corresponde a una clave está ocupada es
preciso probar otras posiciones p0, p1, p2,...
pi(c) = ( f(c) + d(i) ) % m, 0 ≤ i ≤ m-1, d(0)=0

■ Distintas alternativas en función del tipo de desplazamiento d(i).


– Prueba lineal, d(i)=i
– Prueba cuadrática, d(i)=i2
– Doble dispersión, d(i)=i * f2(c)

■ Importante: Se debe asegurar que se pueden examinar todas las


posiciones de la tabla.

Estructuras de datos y algoritmos (TEMA 5) 25


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0
1
2
3

f ( c ) = c % 10 4
5
Insertar (89, “A”)
9 6
7
8
9 89 A

Estructuras de datos y algoritmos (TEMA 5) 26


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0
1
2
3

f ( c ) = c % 10 4
5
Insertar (18, “B”)
8 6
7
8 18 B
9 89 A

Estructuras de datos y algoritmos (TEMA 5) 27


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0
1
2
3

f ( c ) = c % 10 4
5
Insertar (49, “C”)
9 6
7
8 18 B
9 89 A
Colisión:
Prueba 0 falla,
Realizar siguiente prueba en posición (9 + 1) % 10

Estructuras de datos y algoritmos (TEMA 5) 28


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0 49 C

0 1
2
3

f ( c ) = (c % 10 + i) % 10 4
5
Insertar (49, “C”)
6
7
8 18 B
9 89 A

Prueba 1 encuentra posición libre.

Estructuras de datos y algoritmos (TEMA 5) 29


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0 49 C
1
2
3

f ( c ) = (c % 10 + i) % 10 4
5
Insertar (58, “D”)
8 6
7
8 18 B
9 89 A
Colisión:
Prueba 0 falla,
Realizar siguiente prueba en posición (8 + 1) % 10

Estructuras de datos y algoritmos (TEMA 5) 30


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0 49 C
1
2
3

f ( c ) = (c % 10 + i) % 10 4
5
Insertar (58, “D”)
6
9
7
8 18 B
9 89 A
Colisión:
Prueba 1 falla,
Realizar siguiente prueba en posición (8 + 2) % 10

Estructuras de datos y algoritmos (TEMA 5) 31


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0 49 C

0 1
2
3

f ( c ) = (c % 10 + i) % 10 4
5
Insertar (58, “D”)
6
7
8 18 B
9 89 A
Colisión:
Prueba 2 falla,
Realizar siguiente prueba en posición (8 + 3) % 10

Estructuras de datos y algoritmos (TEMA 5) 32


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0 49 C
1 58 D
1 2
3

f ( c ) = (c % 10 + i) % 10 4
5
Insertar (58, “D”)
6
7
8 18 B
9 89 A

Prueba 3 encuentra posición libre,

Estructuras de datos y algoritmos (TEMA 5) 33


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0 49 C
1 58 D
2
3

f ( c ) = (c % 10 + i) % 10 4
5
Insertar (69, “E”)
6

9 7
8 18 B
9 89 A
Colisión:
Prueba 0 falla,
Realizar siguiente prueba en posición (9 + 1) % 10

Estructuras de datos y algoritmos (TEMA 5) 34


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0 49 C

0 1 58 D
2
3

f ( c ) = (c % 10 + i) % 10 4
5
Insertar (69, “E”)
6
7
8 18 B
9 89 A
Colisión:
Prueba 1 falla,
Realizar siguiente prueba en posición (9 + 2) % 10

Estructuras de datos y algoritmos (TEMA 5) 35


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0 49 C
1 58 D
1
2
3

f ( c ) = (c % 10 + i) % 10 4
5
Insertar (69, “E”)
6
7
8 18 B
9 89 A
Colisión:
Prueba 2 falla,
Realizar siguiente prueba en posición (9 + 3) % 10

Estructuras de datos y algoritmos (TEMA 5) 36


Dispersión cerrada: Ejemplo (P. Lineal)

clave valor
Insertar {89, 18, 49, 58, 69}
0 49 C
1 58 D

2 2 69 E
3

f ( c ) = (c % 10 + i) % 10 4
5
Insertar (69, “E”)
6
7
8 18 B
9 89 A

Prueba 3 encuentra posición libre,

Estructuras de datos y algoritmos (TEMA 5) 37


Prueba lineal: Problema

■ La dispersión mediante dispersión cerrada con prueba lineal


tiene un problema de agrupamiento de claves:
– Claves que colisionan en posiciones próximas prueban la
misma secuencia de posiciones y tienden a agruparse en la
tabla.
– Cada vez se hace más difícil (costoso) encontrar una posición
libre.

■ Sería mejor que las claves y los huecos se alternaran en la tabla


para que se pudiera encontrar un hueco en un menor número de
intentos.

Estructuras de datos y algoritmos (TEMA 5) 38


Prueba lineal: Ejemplo de agrupamiento

clav dat
Insertar {89, 18, 49, 58, 69} e o
0 49 C
1 58 D
2 69 E
3
4
f ( c ) = ( c % 10 + i ) % 10
5
6
7
Las claves que han colisionado en las
posiciones 8 y 9 se han agrupado, formando 8 18 B
una secuencia en las posiciones 8, 9, 0, 1, 2. 9 89 A
El resto de la tabla está vacía.

Estructuras de datos y algoritmos (TEMA 5) 39


Dispersión cerrada: Otras estrategias

■ Prueba cuadrática y doble dispersión.


■ Tratan de evitar la formación de agrupamientos de claves y
reducir el número de pruebas necesarias para Buscar/Insertar un
elemento.
■ Tienen el problema de asegurar que se puede examinar toda la
tabla:
■ Prueba cuadrática, d(i) = ± i2 (0 ≤ i ≤ m-1/2).
– Si m es primo de la forma 4j+3 examina todas las
posiciones
■ Doble dispersión, d(i) = i * f2(c)
– f2(c) = R – (c % R), siendo R primo < m
– Ejemplo: m = 1009 y R = 739
■ La mejor opción es realizar doble dispersión.

Estructuras de datos y algoritmos (TEMA 5) 40


Dispersión cerrada: Coste

■ Buscar:
– Hashing + Buscar en la secuencia de posiciones definida por
la estrategia (lineal, cuadrática, doble dispersión) hasta
encontrar la clave o un hueco libre.
– Puede finalizar con éxito (clave encontrada) o con fracaso
(clave no encontrada).
■ Fracaso = Se alcanza una posición libre.
– Factor de carga de la tabla, λ = n/m (claves almacenadas/nº
de posiciones en la tabla) ≡ Fracción de celdas ocupadas.
■ Fracción de celdas libres = 1 – λ
– Número esperado de pruebas para encontrar una posición
1
libre:
1−𝜆𝜆

Estructuras de datos y algoritmos (TEMA 5) 41


Direccionamiento abierto: Coste
1
■ Coste de Insertar = Coste de Buscar con fracaso = O( )
1−𝜆𝜆

■ Búsqueda con éxito = número de pruebas realizadas en el


momento de insertar el elemento = Búsqueda con fracaso en el
momento de la inserción:

1  1 
ln 
λ 1− λ 

■ En direccionamiento abierto es importante mantener la tabla


“suficiente vacía”  A medida que crece λ el coste degenera
rápidamente.
■ Dependiendo de la estrategia: 0,5 ≤ λmax ≤ 0,7

Estructuras de datos y algoritmos (TEMA 5) 42


1. Fundamentos.
Tema 4. 2. Representación.
3. Representación mediante C++/STL.
Tablas 4. Aplicaciones.

43
Implementación en C++ (Clase)
// Tabla Hash con Encadenamiento
class Tabla
{
public:
//Declaracion de los tipos clave y valor
typedef string TipoClave; //sustituir por lo que corresponda
typedef string TipoDato; //sustituir por lo que corresponda
class ParDato //Los datos almacenados en la tabla (Clave, Valor)
{
public:
TipoClave clave;
TipoDato valor;
ParDato(){}
ParDato (TipoClave a, TipoDato b)
:clave(a),valor(b) {}
};

//Operaciones
Tabla(size_t); //t_nula
bool Buscar(TipoClave, TipoDato&) const; //consultar/definida
void Insertar(const ParDato&); //asignar

private:
vector< vector<ParDato> > t; //Encadenamiento
size_t Hash(TipoClave) const;
};

Estructuras de datos y algoritmos (TEMA 5) 44


Implementación en C++ (Clase)
//Declaracion de los tipos clave y valor
typedef string TipoClave; //sustituir por lo que corresponda
typedef string TipoDato; //sustituir por lo que corresponda
typedef pair<TipoClave,TipoDato> TipoParDato; //Datos = (Clave, Valor)

// Tabla Hash con Encadenamiento


class Tabla
{
public:
Tabla(size_t); //t_nula
bool Buscar(const TipoClave, TipoDato&) const; //consultar/definida
void Insertar(const TipoParDato&); //asignar
//Busqueda/Insercion con []
TipoDato& operator[](const TipoClave);
//Definida Clave en la tabla, true/false
bool Existe(const TipoClave) const;

private:
//Encadenamiento, cada posición del vector t es un vector.
vector<vector<TipoParDato>> t;
//Función de dispersión.
size_t Hash(TipoClave) const;
};

Estructuras de datos y algoritmos (TEMA 5) 45


Implementación en C++ (Operaciones)
//Constructor: establece el tamaño de la tabla
Tabla::Tabla(size_t tam)
{
t.resize(tam); //Crea todas las posiciones = todos los indices
}

bool Tabla::Buscar(const TipoClave cl, TipoDato & va) const


{
size_t ind, j;
bool enc = false;

ind = Hash(cl);
j = 0;
while ( j<t[ind].size() && !enc ) //Búsq. secuencial en el vector t[ind]
if ( t[ind][j].clave == cl )
{
va = t[ind][j].valor;
enc = true;
}
else j++;
return enc;
}

Estructuras de datos y algoritmos (TEMA 5) 46


Implementación en C++ (Operaciones)
void Tabla::Insertar(const ParDato& x)
{
TipoParDato tmp(x.clave,x.valor); //Necesario por argumento const

if (! Buscar (tmp.clave,tmp.valor) )
//Añadir al final del vector correspondiente
t[Hash(x.clave)].push_back(x);
}

size_t Tabla::Hash(TipoClave c) const


{
size_t suma = 0;
for (size_t i = 0; i < c.length(); i++)
suma = (suma << 5) + c[i];
return suma%t.size(); //El tamaño de la tabla lo indica t.size()
}

Estructuras de datos y algoritmos (TEMA 5) 47


Implementación en C++ (Operaciones)
TipoDato& Tabla::operator[](TipoClave cl)
{
size_t ind, j;
bool enc = false;
TipoDato* va = nullptr; //Para devolver referencia al dato

ind = Hash(cl);
j = 0;
while ( j < t[ind].size() && ! enc ) //Búsqueda secuencial en el vector
if (t[ind][j].first == cl )
{
va = &t[ind][j].second; //Dirección del valor encontrado
enc = true;
}
else j++;
if ( !enc )
{
//Añadir al final del vector correspondiente con un dato por defecto
t[ind].push_back(make_pair(cl,TipoDato()));
va = &t[ind][t[ind].size()-1].second; //Dirección del valor añadido
}
return *va; //valor referenciado por va
}

Estructuras de datos y algoritmos (TEMA 5) 48


Implementación en C++ (Operaciones)

bool Tabla::Existe(const TipoClave cl) const


{
size_t ind, j;
bool enc = false;

ind = Hash(cl);
j = 0;
while ( j < t[ind].size() && ! enc ) //Búsq. secuencial en el vector t[ind]
if (t[ind][j].first == cl )
enc = true;
else j++;
return enc;
}

Estructuras de datos y algoritmos (TEMA 5) 49


1. Fundamentos.
Tema 4. 2. Representación.
3. Representación mediante C++/STL.
Tablas 4. Aplicaciones.

50
TAD Tabla en C++ (STL)
■ En la biblioteca estándar de C++ (STL) podemos encontrar
diversos contenedores que responden al TAD Tabla:
ABB rojo-negro
– map: Tabla con clave única.
– multimap: Tabla que admite duplicado de claves.
– set: Conjunto. Es una tabla que únicamente contiene claves.
– multiset: Conjunto con elementos repetidos.
Tablas hash con encadenamiento
– unordered_map
– unordered_multimap
– unordered_set
– unordered_multiset

Estructuras de datos y algoritmos (TEMA 5) 51


Ejemplo: map

■ Crear un “mapa” (tabla, diccionario) con datos del tipo


– Clave = string
– Valor = int

#include <map>
map<string,int> m;

■ Las parejas clave-valor se guardan juntas en una estructura


pair, cuyos campos se llaman first y second
(pair<string,int>).

Estructuras de datos y algoritmos (TEMA 5) 52


Insertar en map

■ Insertar una nueva pareja clave-valor:

– Opción 1: Operación insert


m.insert( pair<string,int>(“juan”, 3) );

– Opción 2: Operador []
m[“juan”] = 3;

Importante: si “juan” ya existe, [] modifica el valor asociado.

Estructuras de datos y algoritmos (TEMA 5) 53


Buscar en map
■ Buscar (consultar) el valor asociado a una clave:

– Opción 1: Operación find


map<string,int>::iterator it;
it = m.find(“juan”);
if ( it != m.end() )
cout << it->first << “ tiene valor ” << it->second;
else
cout << “No encontrado”;

– Opción 2: Operador []
cout << m[“juan”];
Importante: si “juan” no existe, lo crea sin valor asociado (!!!).

– Opción 3: Operación count


if ( m.count(“juan”) > 0)
cout << “juan existe”;

Estructuras de datos y algoritmos (TEMA 5) 54


Buscar en map

■ Mostrar (Recorrer) el mapa completo:

map<string,int>::iterator it;
for ( it = m.begin(); it != m.end(); it++ )
cout << “clave:” << it->first << “ dato:”
<< it->second << endl;

■ Iteradores (iterator): permiten recorrer (iterar) un contenedor


sin saber cómo es su implementación.
■ Iteradores especiales:
■ begin(): primer elemento del contenedor.
■ end(): una “posición” más allá del último elemento del contenedor.

Estructuras de datos y algoritmos (TEMA 5) 55


Función Hash: hash

■ Se puede usar una función hash con independencia de una tabla


hash.
■ hash es un objeto función (objeto con apariencia de función, por
la sobrecarga del operador ()) que devuelve un valor de hash
calculado a partir de su argumento.
– Es un entero sin signo (size_t), sin normalizar.
■ Ejemplo: #include <iostream>
#include <functional>
#include <string>
Using namespace std;
int main ()
{
string str = "Clave";

hash<string> f_hash; //Es un objeto, no una función

cout << "str: " << str << " valor hash: " << f_hash(str) << endl;

return 0;
}

Estructuras de datos y algoritmos (TEMA 5) 56


1. Fundamentos.
Tema 4. 2. Representación.
3. Representación mediante C++/STL.
Tablas 4. Aplicaciones.
(Mapas o
Diccionarios)

57
Hashing espacial

■ Cálculo rápido de colisiones de partículas en el espacio.

Estructuras de datos y algoritmos (TEMA 5) 58


Estructuras de datos y algoritmos (TEMA 5) 59
vídeo
Estructuras de datos y algoritmos (TEMA 5) 60
Estructuras de datos y algoritmos (TEMA 5) 61

También podría gustarte