2. CONCEPTOS
Conjunto
– Colección de elemento
– Todos los elementos son distintos (no se repiten)
– Todos los elementos son del mismo tipo
– Enteros, caracteres , cadenas, otro conjuntos, etc.
– Elementos no tienen un orden específico
1
7
8
9
A
3. NOTACION DE CONJUNTOS
• Encerrando sus elementos en llaves
– Ejemplo: {1,4}
– Recuerde que {1,4} es lo mismo que {4,1}
• O de la forma {x | proposición sobre x}
– Ejemplo: { x | 7 x < 30} o
– {x | para algún entero y, x = y+1}
4. PERTENENCIA
• Relación fundamental en la teoría de conjuntos
• Dado un conjunto A
– x A indica que x es elemento de A
– x A indica que x no es elemento de A
• Un conjunto sin elemento
– Es un conjunto vacio, se denota
– x es falso para todo x
5. SUBCONJUNTO
• Un conjunto A esta incluido en uno B
– Si todo elemento de A es elemento de B
– A B o B A
– A es un subconjunto de B o
– B es un supraconjunto de A
• Ejemplo:
– {1,2} {1,2,3}
• Todo conjunto esta incluido en si mismo
• El conjunto vacio esta incluido en todo conjunto
6. OPERACIONES ELEMENTALES
• Si A y B son conjuntos
A B es la unión de A y B
Conjunto de elementos que son miembros de A, de B o de ambos
A B es la intersección de A y B
Conjunto de elementos que pertenecen tanto a A como a B
A B es la diferencia
Conjunto de elementos de A que no pertenecen a B
• Ejemplo:
– A = {a,b,c} y B = {b,d}
– A B = {a,b,c,d}; A B = {b} y A B = {a,c}
7. OPERACIONES DEL TDA CONJUNTO
• Básicas
– Conjunto Union(Conjunto A, Conjunto B)
– Conjunto Interseccion(Conjunto A, Conjunto B)
– Conjunto Diferencia(Conjunto A, Conjunto B)
• Generales
– bool EsMiembro(Conjunto A, Info x)
• Determina si el elemento x se encuentra en el conjunto A
– void Vaciar(Conjunto A)
• Convierte al conjunto A en un conjunto vacio
8. MAS OPERACIONES GENERALES
• void Suprimir(Conjunto A, Info x)
– Remueve el elemento x del conjunto A
• Info Min(Conjunto A), Info Max(Conjunto A)
– Retornan el valor mínimo y máximo del conjunto A
• bool Igual(Conjunto A, Conjunto B)
– Determina si los conjuntos A y B tienen los mismos elementos
9. REPRESENTACIONES
• Hay varias formas de representar un conjunto
• Implementaciones básicas
– Usando vectores de bits
– Usando listas
• Tablas de Dispersión
10. VECTORES DE BITS
• Si el conjunto que se va a manejar
– Es subconjunto del conjunto de enteros positivos,
– Puede usarse vectores de bits
• Un vector de bits es un arreglo booleano
– Si el elemento de posición i almacena
• 1: i es miembro del conjunto
• 0: i no es miembro del conjunto
0
0
0
1
0
2
0
3
0
4
0
5
0
6
0
7
0
8
0
9
0
10
7,10,1,4A 11 11
11. DECLARACION CON VECTORES DE BITS
• Se necesita
– Un arreglo de bits
– Un tamaño máximo
0
0
0
1
0
2
0
3
0
4
0
5
0
6
0
7
0
8
0
9
0
10
7,10,1,4A 11 11
12. ALGUNAS OPERACIONES
Conjunto Union(Conjunto A, Conjunto B){
int i;
Conjunto C;
for(i = 0; i < MAX;i++)
C[i] = A[i] || B[i];
return C;
}
Conjunto Interseccion(Conjunto A, Conjunto B){
int i;
Conjunto C;
for(i = 0; i < MAX;i++)
C[i] = A[i] && B[i];
return C;
}
0
0
0
1
0
2
1,0A 1 1
0
0
0
1
0
2
2,1B 11
13. • También se los puede representar con listas
– No hay desperdicio de espacio
– No es solo para conjuntos de enteros
– Representa cualquier tipo de conjunto
• Listas Ordenadas
– Esto ayuda a la eficiencia de la implementación
– Si queremos saber si x es miembro del conjunto
• No tenemos que revisar toda la lista
• Solo hasta encontrar un elemento >= x
DECLARACION CON LISTAS
14. INTERSECCION: Recorriendo la lista. Aprovechar
el orden
• Comparamos uno a uno con los
elementos de B(xB)
2 5 25 318
lastheader
A
5 19 2524
lastheader
B
A B. Ejemplo:
A = {25,5,8,2,31} y
B = {24,5,25,19}
Comenzamos un elemento de A(xA)
xA
xB
Si xA es menor que xB,
xA ya no puede estar en B
Pasamos a otro xA
xA
Si xA es igual a xB,
Añadir xA al nuevo conjunto
Pasamos a otro xA y otro XB
5C
xB
xA xA
Si xA es mayor a xB,
xA aun puede estar en B
Probamos con otro XB
xB xB
25
xB
xA
Si XA o XB llegan a
null, termina la
revisión
15. UNION: Usando métodos de LinkedList
public static LinkedList union (LinkedList c1, LinkedList c2){
LinkedList retorno = new LinkedList();
retorno.addAll(c1);
retorno.removeAll(c2);
retorno.addAll(c2);
Collections.sort(retorno);
return retorno;
}
2 5 25 318
5 19 2524
2 5 25 318
A
B
2 318
5 19 2524
16. INTERSECCION: Usando métodos de LinkedList
public static LinkedList interseccion (LinkedList c1, LinkedList c2){
LinkedList retorno = new LinkedList();
retorno.addAll(c1);
retorno. retainAll(c2);
return retorno;
}
2 5 25 318
5 19 2524
2 5 25 318
A
B
5 25
17. DIFERENCIA: Usando métodos de LinkedList
public static LinkedList diferencia (LinkedList c1, LinkedList c2){
LinkedList retorno = new LinkedList();
retorno.addAll(c1);
retorno.removeAll(c2);
return retorno;
}
2 5 25 318
5 19 2524
2 5 25 318
A
B
2 318
18. • Set: no tiene orden entre
sus elementos
• SortedSet: elementos
dentro del conjunto de la
colección están ordenados
(orden natural o usando
Comparator). Facilita acceso
para búsquedas, y consultas
rápidas
IMPLEMENTACIÓN EN JAVA: INTERFAZ Set y
SortedSet
19. • HashSet: no tiene orden
entre sus elementos
• LinkedHashSet: Incluye
ordenación de elementos
por orden de entrada,
una velocidad de
iteración mucho mayor y
un rendimiento peor a la
hora de añadir
elementos.
IMPLEMENTACIÓN DE INTERFAZ Set
21. • TreeSet : Está basada
en el uso de una
estructura de árbol
permitiendo que los
elementos estén
ordenados (orden
natural o por un
Comparator).
Implementación de Interfaz SortedSet
24. TDA MAPA
• Los mapas (o diccionarios) asocian un valor (value) con una
clave (key). Tanto la clave como el valor pueden ser
cualquier tipo de datos de Java (primitivos o compuestos).
• Los mapas utilizan internamente a conjuntos para garantizar
que no hay elementos duplicados en las claves.
25. REPRESENTACIONES
Se puede representar un mapa implementando su clave como
un conjunto:
• Implementaciones básicas
– Usando vectores de bits
– Usando listas
• Tablas de Dispersión
26. • Map: No puede tener
claves duplicadas. La
clave funciona como un
identificador único
IMPLEMENTACIÓN EN JAVA: INTERFAZ MAP
27. • HashMap: Implementa la
interfaz Map basada en
una tabla de dispersión
(no sincronizadas, permite
una clave nula, y valores
nulos).
• Hashtable : Implementa la
interfaz Map basada en
una tabla de dispersión
(sincronizadas, no permite
null).
IMPLEMENTACIÓN EN JAVA: INTERFAZ MAP
28. • size() Devuelve el número de elementos del mapa
• isEmpty() Devuelve true si no hay elementos y false si los hay
• clear() vacia el mapa
• put(K key, V value) Añade un elemento al mapa. Si ya existe lo reemplaza y retorna el
antiguo valor
• get(K key) Retorna el valor relacionado a la clave que se le pasa como parámetro o null si
la clave no existe
• getOrDefault(K key, V value) Retorna el valor relacionado a la clave o devuelve valor por
defecto si no existe
• remove(K key) Elimina el par clave/valor de la clave que se le pasa como parámetro
• keySet() Retorna el conjunto de claves del mapa
• containsKey(K key) chequea si el mapa contiene clave especificada
• containsValue(V value) devuelve verdadero si en el mapa hay un Valor que coincide con
V
METODOS DE HashMap
32. MAP- SET (POSIBLES REPRESENTACIONES)
Vectores de Bits
– El tiempo de las operaciones
es constante
– Limitado en el dominio de sus
elementos
– Desperdicio de memoria
Listas enlazadas(ordenadas)
El tiempo de las operaciones
Depende el número de elementos.
O(N)
Elementos pueden ser de cualquier
tipo
0
0
1
1
0
2
0
3
1
4
1
5
0
6
0
7
0
8
0
9
0
10
5,1,4A
4 1 5
lastfirst
33. MAP- SET (POSIBLES REPRESENTACIONES)
Problema
– Almacenar las n claves del espacio D en una tabla de tamaño m sin
desperdiciar memoria.
Solución
• Definir una función que permita traducir y comprimir la clave a un índice
de una tabla , cuyo tamaño sea proporcional al número de elementos
almacenados en vez de al número de claves posibles
34. FUNCION DE DISPERSION
• También: Función de conversión o Hash: h(x)
• Transforma una clave en índice de almacenamiento
– La clave puede ser de cualquier tipo (usualmente un string o un
entero)
• La función hash debe
– Distribuir claves uniformemente
– Generar un índice entre 0 y m-1
– Tener un algoritmo sencillo
35. DISPERSION O HASHING
• Dado una tabla de B filas
– Cada fila se llama: Cubeta
• Queremos distribuir los elementos en
las cubetas
– Se usará una función de dispersión
– Con la clave del elemento,
• La función calculará a que cubeta deberá ir
dicho elemento
A = {4,6,16,12,21,36}
B
0
1
2
3
4
5
6
h(4) = 4
4
h(6) = 6
6
h(16) = 2
16
h(12) = 5
12
h(21) = 0
21
36
h(36) = 1
36. POSIBLES H(x)
Aritmética modular
– El índice se obtiene: clave%B
– Conviene que ncubetas sea primo y cercano al número de claves a
guardar
A = {4,6,16,12,21,36}
7
0
1
2
3
4
5
6
4
h(k) = k%7
6
16
12
21
36
factor de carga = n/m 0.86
Es recomendable que factor de carga
sea menor a 0.80
38. POSIBLES H(x)
Mitad del cuadrado
– Elevar al cuadrado la clave
– Tomar los dígitos de una determinada posición (la misma para
todos)
– El número de dígitos depende del rango del índice
– Ejemplo:
• si B: 100 y clave = 256,
• Tomaremos 2 dígitos de pos: 1 y 3 (desde derecha)
• índice: 2562 = 65536 = Tomamos 56
40. POSIBLES H(x)
Plegamiento
– Consiste en dividir la clave en segmentos
– Luego aplicarles alguna operación
– Ejemplo: “DAVID”
• Sumar los códigos ASCII divididos en grupos de 2
68 + 6586 + 7368 = 14022
D A V I D
68 65 86 7368
42. POSIBLES H(x)
Truncamiento
– Tomar directamente d dígitos de la clave
– En posiciones fijas
– Ejemplo:
• B = 1000, tomar siempre 5, 2, 1
• clave = 72588495, índice = 895
43. ¿Dos claves pueden tener el mismo índice?
– Si, este caso se conoce como colisión
– Para estos casos hay dos estrategias de colisión
• Hashing Abierto
• Cada cubeta almacena un conjunto de elementos
• Hashing Cerrado
• Cada elemento va en una cubeta
• Si hay colisión se aplica redispersión
• Aplicar otra función hash de reserva
• Y se intenta de nuevo
TRATAMIENTO DE COLISIONES
44. HASHING ABIERTO
• Supongamos que
– Hay colision entre d1,d2,..dn, es decir
– H(d1) = H(d2) = H(dn)
• Todos estos elementos
– Se asignan a la misma cubeta
– Son parte de la lista de elementos de dicha
cubeta
• La cubeta no tiene limites de
almacenamiento
B
0
1
2
3
4
5
6
A = {2,5,16,8,1}
h(2) = 2
2
h(5) = 5
5
h(16) = 2
, 16
h(8) = 1
8
h(1) = 1
, 1
46. HASHING CERRADO
• Una cubeta para un elemento
• Si se da una colisión
– Se aplica otra función hash, hi(x)
– Donde i, es el número de colisión para
el elemento x
– Se intenta de nuevo(redispersión)
• Si hay elementos en todas las cubetas
– La tabla esta llena
– No se puede insertar el elemento
B
0
1
2
3
4
5
6
A = {2,5,16,8,1} h(2) = 2
2
h(5) = 5
5
h(16) = 2
8
h1(16) =3
16
h(8) = 1
h1(1) =2
h2(1) =3
h3(1) =4
1
h(1) = 1
hi(x) = (h(x) + i)
47. POSIBLES Hi(X)
• Rehash Lineal
– hi(x) = (h(x) + i)
– Agrupa cubetas llenas en grandes bloques consecutivos
• Rehash Cuadrático
– hi(x) = (h(x) + i2)
• Hash con Doble Función
– hi(x) = (h(x) + i*h’(x))
– h’(x) es otra función
48. EJEMPLO
• Suponga que B = 8 y que
• Elementos a,b,c,d tienen
– h(a) = 3, h(b) = 0, h(c) = 4, h(d) = 3
• Insertemos con redispersión lineal
B=8
0
1
2
3
4
5
6
7
Insertar: a, cubeta = 3
a
Insertar: b, cubeta = 0
b
Insertar: c, cubeta = 4
c
Insertar: d, cubeta = 3
Redispersar: h1(d) =
h(d) + 1
d
Redispersar: h2(d) =
h(d) + 2
49. IMPLEMENTACION EN JAVA
(Hashtable-HashMap)
• En Java la clase Object (todas las clases la heredan) tiene una
implementación por defecto de función de dispersión hashCode()
• Cuando Java compara dos objetos en estructuras de tipo hash
(HashMap, HashSet etc) primero invoca al método hashcode para
ubicar su posición en la estructura y luego equals para determinar si
encontró al objeto adecuado
• Por defecto es la dirección de memoria del objeto convertido a entero.
La clase String tiene su propia implementación de hashCode() basada
en la función:
• Si dos objetos son iguales (equals == true), DEBEN tener el mismo
código hash.
• Dos objetos diferentes (equals == false) pueden tener el mismo
código hash.
50. Ejemplo: crear una tabla de nombres cuyas claves son
coordenadas
IMPLEMENTACION EN JAVA
(Hashtable-HashMap)
51. IMPLEMENTACION EN JAVA (Hashtable)
Ejemplo: crear una tabla de nombres cuyas claves son
coordenadas
52. Vectores de Bits
– El tiempo de las operaciones
es constante
– Limitado en el dominio de sus
elementos
Listas enlazadas(ordenadas)
– El tiempo de las operaciones
• Depende el numero de
elementos. O(N)
– Elementos pueden ser de
cualquier tipo
Dispersion o Hashing
En el mejor de los casos
Tiempo constante por operación
En el peor de los casos
Tiempo proporcional al tamaño
del conjunto(N)
Conjuntos pueden ser de cualquier
tipo
Hashtable permite manejo sincrónico, lo cual permite ejecuciones multi-hilo.
Hashtable no permite nulos (ni claves, ni valores).
HashMap permite una clave nula y cualquier cantidad de valores nulos.
53. EJERCICIO
Considere un HashMap<String,LinkedList> que tiene como clave un usuario de Twitter y como valor una
lista de mensajes que le pertenecen al usuario. Los mensajes pueden contener menciones a otros
usuarios de Twitter.
{
"@user1" : ["Saludos @user2 y @user3" , "Respondeme @user2"] ,
"@user2" : ["Hola @user3 y @user4" , "Saludos @user4"] ,
"@user3" : ["Hoy me siento genial" , "Es un hermoso día"] ,
…
}
A usted se le solicita implementar la función mencionesPorUsuario, la función recibe el mapa con los
mensajes de todos los usuarios y retorna un HashMap<String,LinkedList> donde la clave es un usuario
de Twitter y el valor es una lista con los usuarios que lo han mencionado.
{
"@user2":["@user1"] ,
"@user3":["@user1" , "@user2"] ,
"@user4":["@user2"] ,
…
}
public static HashMap <String,LinkedList> mencionesPorUsuario ( HashMap <String,LinkedList> tw)
55. EJERCICIO
Una empresa almacena los registros (logs) de los sitios web que visita el personal en la organización con
su respectivo tiempo de conexión. Los registros se encuentran en una lista con el siguiente formato:
logs = [
"user1|www.facebook.com|30",
"user2|www.google.com|20",
"user1|www.facebook.com|40",
"user1|www.twitter.com|20",
...
]
A usted se le solicita implementar la siguiente función:
public HashMap<String,HashMap<String,Integer>> crearMapaVisitas(LinkedList<String> logs)
Esta función retorna un mapa con la siguiente estructura:
visitas = {
"user1":{ "www.facebook.com":70, "www.twitter.com":20 },
"user2":{ "www.google.com":20 },
..
}