022_diccionarios
TRANSCRIPT
![Page 1: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/1.jpg)
Análisis y diseño de software dit UPM
Tema 2: Algoritmos /diccionarios
José A. Mañas http://jungla.dit.upm.es/~pepe/doc/adsw/index.html
8.3.2013
![Page 2: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/2.jpg)
referencias
• En la web
– diccionarios / dictionaries
– tablas de símbolos / symbol tables
– lookup tables
– map
– algoritmos de búsqueda / search algorithms
diccionarios 2
![Page 3: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/3.jpg)
Map: memoria asociativa
• Map<Clave, Valor> tabla= new HashMap<Clave, Valor>;
• tabla.put(“rojo”, “red”); tabla.put(“verde”, “green”); tabla.put(“negro”, “black”);
• String ingles = tabla.get(“rojo”);
hash 3
![Page 4: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/4.jpg)
Set: conjunto
• Set<String> grupo= new HashSet<String>;
• grupo.add(“Juan”); grupo.add(“Ana”);
• grupo.contains(“Ana”) TRUE
hash 4
![Page 5: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/5.jpg)
índice
• arrays
• arrays ordenados
• árboles binarios de búsqueda
• tablas hash con listas
• tablas hash abiertas
• estructuras de datos de java
– HashMap
– TreeMap
diccionarios 5
![Page 6: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/6.jpg)
interface Diccionario • public void put(Comparable clave, Object valor);
– mete un valor nuevo – ¿reemplaza a uno ya existente con misma clave?
• public Object get(Comparable clave);
– saca el valor asociado a la clave – null si no está la clave
• public Object remove(Comparable clave);
– elimina el objeto asociado a la clave, si está – devuelve null si no está la clave – devuelve el valor asociado si estaba la clave
• public int size();
– número de elementos almacenados
diccionarios 6
![Page 7: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/7.jpg)
duplicados
• al meter ¿qué pasa si se mete un clave que ya está? – hay algoritmos que reemplazan el valor anterior
– hay algoritmos que meten un nuevo valor
– usaremos lo más sencillo indicando si se reemplaza o se duplica
• al sacar – sacaremos lo primero que encontremos
• al quitar – borraremos lo primero que encontremos
diccionarios 7
![Page 8: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/8.jpg)
Comparable clave
interface Comparable { int compareTo() }
int cmp = clave1.comparteTo(clave2)
• cmp < 0 si clave1 < clave2
• cmp = 0 si clave1 = clave2
• cmp > 0 si clave1 > clave2
• relación de orden total
diccionarios 8
![Page 9: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/9.jpg)
banco de pruebas funcionales public class DiccionarioTest { private Diccionario diccionario; @Before public void setUp() { diccionario = new DiccionarioArray(100); diccionario.put("Cervantes", "Miguel de Cervantes"); diccionario.put("America", "12 de octubre de 1492"); diccionario.put("Revolucion", "1789"); assertEquals(3, diccionario.size()); } @Test public void test001() { assertNull(diccionario.get("kaka")); assertEquals("Miguel de Cervantes", diccionario.get("Cervantes")); assertEquals("12 de octubre de 1492", diccionario.get("America")); assertEquals("1789", diccionario.get("Revolucion")); }
diccionarios 9
![Page 10: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/10.jpg)
con arrays
• put – se añade al final (sin detectar duplicados)
– O(1)
• get – recorre el array comparando
– O(n)
• remove – recorre el array comparando
– O(n)
diccionarios 10
![Page 11: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/11.jpg)
arrays ordenados
búsqueda binaria
• miramos en la mitad del array
• si ahí está el dato que buscamos, esa es la respuesta
• si ahí hay un dato demasiado grande entonces hay que buscar por la izquierda
• si no entonces hay que buscar por la derecha
diccionarios 11
![Page 12: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/12.jpg)
busca iterativo // busca en el rango [a, z) private int busca(Comparable clave, int a, int z) { while (a < z) { int m = (a + z) / 2; int cmp = claves[m].compareTo(clave); if (cmp == 0) return m; else if (cmp < 0) a = m + 1; else z = m; } return a; }
diccionarios 12
![Page 13: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/13.jpg)
ejemplo
• int[] datos = {2, 3, 5, 7, 11, 13, 17, 19}; • busca(3, 0, 8)
– a = 0; z = 8; m = 4; datos[m] = 11 – a = 0; z = 4; m = 2; datos[m] = 5 – a = 0; z = 2; m = 1; datos[m] = 3 – return 1 donde está el dato
• busca(4, 0, 8) – a = 0; z = 8; m = 4; datos[m] = 11 – a = 0; z = 4; m = 2; datos[m] = 5 – a = 0; z = 2; m = 1; datos[m] = 3 – a = 2; z = 2 – return 2 donde estaría el dato
diccionarios 13
![Page 14: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/14.jpg)
complejidad
• caso mejor: a la primera: O(1)
• caso peor: bucle da un máximo de k vueltas 1. n datos
2. n/2 datos
3. n/4 datos
k. n/2k datos
• despejando k = log2 (n)
• complejidad caso peor – O(log2 (n)) = O(log n)
diccionarios 14
![Page 15: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/15.jpg)
con arrays ordenados • put
– busca la posición donde entraría – reemplaza O(1) – hace sitio desplazando n/2 O(n) – peor: O(put) = O(busca) + O(n/2) = O(log n) + O(n) = O(n)
• get – busca la posición de donde saldría – saca o null – O(get) = O(busca) = O(log n)
• remove – busca la posición donde estaría – null o hay que desplazar n/2 – peor: O(remove) = O(busca) + O(n/2) = O(log n) + O(n) = O(n)
diccionarios 15
![Page 16: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/16.jpg)
arrays ordenados - búsqueda binaria
• programación recursiva
• programación iterativa
• ¿cuál será más rápida?
diccionarios 16
![Page 17: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/17.jpg)
comparación
1. medir tiempos
– arrays
– arrays con búsqueda binaria recursiva
– arrays con búsqueda binaria iterativa
2. ¿conclusiones?
diccionarios 17
![Page 18: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/18.jpg)
banco de pruebas de tiempos (1)
public class BancoPruebas { public static final int CASOS = 100; public static final int MAX = 10000000; private static int[] datos; private static int algoritmo; public static void main(String[] args) { algoritmo = 0; // lineal // algoritmo= 1; // binario iterativo // algoritmo= 2; // binario recursivo Random random = new Random(); // datos de prueba datos = new int[MAX]; for (int i = 0; i < MAX; i++) { int clave = random.nextInt(MAX); datos[i] = clave; } if (algoritmo > 0) Arrays.sort(datos); diccionarios 18
![Page 19: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/19.jpg)
banco de pruebas de tiempos (2)
// forzamos al compilador a optimizar código for (int i = 0; i < 100; i++) { int clave = random.nextInt(100); busca(clave, 100); } • una alternativa es ejecutar sin JIT
java -Djava.compiler=NONE dictionaries/BancoPruebas – esto no da valores absolutos realistas
pero permite estudiar la tedencia de forma estable
diccionarios 19
![Page 20: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/20.jpg)
banco de pruebas de tiempos (3)
// pruebas int[] tamanos = { 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000, }; for (int N : tamanos) { long t0 = System.nanoTime(); for (int i = 0; i < CASOS; i++) { int clave = random.nextInt(N); busca(clave, N); } long t2 = System.nanoTime(); System.out.printf("%,10d: %,12d%n", N, (t2 - t0)); }
diccionarios 20
![Page 21: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/21.jpg)
tiempos de búsqueda
diccionarios 21
sin precalentamiento
![Page 22: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/22.jpg)
ordenación perezosa
• Si en un objeto
– hay que meter datos (comparables)
– hay que buscar datos
• ¿qué nos interesa más?
1. inserción ordenada + búsqueda binaria
2. inserción tal cual + búsqueda lineal
3. inserción + ordenación + búsqueda binaria
– depende de la proporción de cada operación
diccionarios 22
![Page 23: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/23.jpg)
ordenación perezosa
• metemos sin preocuparnos del orden
– datos[pos++] = nuevo dato; ordenada = false;
• cuando hay que sacar ordenamos
– if (ordenada = false) { sort(datos, 0, pos); ordenada = true; } return busqueda_binaria(datos, dato)
diccionarios 23
![Page 24: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/24.jpg)
árboles binarios de búsqueda
• Grafo
– cada nodo padre tiene 2 hijos
– hijo izquierdo; valor(hijo) < valor(padre)
– hijo derecho; valor(hijo) > valor(padre)
diccionarios 24
![Page 25: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/25.jpg)
árbol binario - estructura
public class DiccionarioArbol implements Diccionario { private class Nodo { Comparable clave; Object valor; Nodo izq; Nodo der; } private Nodo raiz; private int n; diccionarios 25
clave
valor
izq der
![Page 26: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/26.jpg)
árbol binario - búsqueda public Object get(Comparable clave) { return get(raiz, clave); } private Object get(Nodo nodo, Comparable clave) { if (nodo == null) return null; int cmp = nodo.clave.compareTo(clave); if (cmp == 0) return nodo.valor; else if (cmp > 0) return get(nodo.izq, clave); else return get(nodo.der, clave); }
diccionarios 26
![Page 27: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/27.jpg)
árbol binario - inserción // detecta duplicados: reemplaza el valor public void put(Comparable clave, Object valor) { raiz = put(raiz, clave, valor); } private Nodo put(Nodo nodo, Comparable clave, Object valor) { if (nodo == null) { nodo = new Nodo(); nodo.clave = clave; nodo.valor = valor; n++; return nodo; } Comparable claveDelNodo = nodo.clave; int cmp = claveDelNodo.compareTo(clave); if (cmp == 0) nodo.valor = valor; // reutilizamos el nodo else if (cmp > 0) nodo.izq = put(nodo.izq, clave, valor); else nodo.der = put(nodo.der, clave, valor); return nodo; } diccionarios 27
![Page 28: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/28.jpg)
árbol binario - eliminación
• caso 1: sin hijos
– se retira el enlace del padre
• caso 2: 1 hijo
– se reemplaza por el hijo
• caso 3: 2 hijos
1. se busca el mayor hijo izquierdo
2. reemplaza al nodo a eliminar
– [… o el menor hijo derecho]
diccionarios 28
![Page 29: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/29.jpg)
árbol binario - eliminación
• queremos eliminar el 7
• el mayor hijo por la izquierda: 6
• eliminamos el 6
– caso 2: no tiene hijos por la derecha
• el 6 reemplaza al 7
diccionarios 29
![Page 30: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/30.jpg)
árbol binario - complejidad
• todas las operaciones recorren un árbol
• sea k la profundidad (o altura) del árbol
– búsqueda - get
• T(n) = c × k
– inserción - put
• T(n) = c × k
– eliminación - remove
• T(n) = T(busca nodo) + T(busca nieto) + T(inserta)
diccionarios 30
![Page 31: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/31.jpg)
árbol ideal = equilibrado
• árbol completo
• N = 20 + 21 + 22 + … + 2k-1 = 2k -1
diccionarios 31
generalizando, para N nodos necesitaremos 𝑘 = log2 𝑁
![Page 32: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/32.jpg)
árbol degenerado
diccionarios 32
mete(“A”); mete(“B”); mete(“C”); mete(“D”); mete(“E”); mete(“F”); mete(“G”);
A
B
G
F
E
D
C
• profundidad k = N
![Page 33: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/33.jpg)
árbol binario - complejidad
• suponiendo que – los casos degenerados son la excepción
– el caso medio estará bastante equilibrado
• búsqueda – O(log n)
• inserción – O(log n)
• eliminación – busca sitio busca nieto inserta
– O(log n) + O(log n) + O(1) = O(log n)
![Page 34: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/34.jpg)
tablas hash
• hash con listas de desbordamiento
• hash abierto
diccionarios 34
![Page 35: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/35.jpg)
hash - motivación
• se trata de tener operaciones de inserción y búsqueda
– tiempo constante: O(1)
• son un ejemplo de
– o invertimos en memoria RAM
– o invertimos en tiempo de CPU
hash 35
![Page 36: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/36.jpg)
tabla hash: un hueco para una clave
• Tenemos una tabla holgada donde caben muchos valores
• A partir de la clave elegimos dónde colocar el valor
hash 36
clave h() tabla[]
![Page 37: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/37.jpg)
función hash
• Si tenemos una tabla de N posiciones
• int h(Clave x) – acepta un objeto x
– genera un valor [0 .. N-1]
• En java, todos los objetos tienen un método – int hashcode()
– int h(Object x) { int codigo = Math.abs(x.hashcode()); return codigo % N; }
hash 37
![Page 38: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/38.jpg)
si no es java o no nos gusta hashcode()
• entonces tiene que inventarse algo
– que sea rápido
– que disperse bien los valores (sin colisiones)
• por ejemplo int h(String s) { int n = 0; for (char ch : s.toCharArray()) n = n * 31 + ch; return n; }
hash 38
![Page 39: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/39.jpg)
si no nos gusta hashcode()
public class Estado {
private final int izq, der;
public Estado(int izq, int der) { this.izq = izq; this.der = der; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Estado estado = (Estado) o;
return der == estado.der && izq == estado.izq;
}
@Override
public int hashCode() {
return 100 * izq + der;
}
}
hash 39
![Page 40: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/40.jpg)
colisiones
• ¿Qué hacer si colisionan? – if (h(x1) == h(x2)) { ... }
• Soluciones 1. lista de valores
• operaciones de meter, sacar y buscar en listas
2. direccionamiento abierto • se buscan otros posibles huecos, de forma metódica,
hasta que encuentra un hueco vacío
• debe haber algún sitio vacío
• es difícil eliminar
hash 40
![Page 41: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/41.jpg)
hash con lista de valores
• En lugar de 1 valor ponemos una lista de valores
– List<Valor>[] tabla
hash 41
List<Valor> : size() = 1
List<Valor> : size() = 2
List<Valor> : size() = 1
List<Valor> : size() = 1
![Page 42: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/42.jpg)
tablas hash con listas
• complejidad – depende de la complejidad de las listas
• insertar, buscar, eliminar – O(1) + O(operación en la lista)
• si hay k entradas y las claves están uniformemente distribuidas – lista.size() ∼ N/k
– el tiempo se divide por k
– complejidad ∼ O(1) + O(N/k) = O(N)
• gastamos RAM; pero ahorramos tiempo
diccionarios 42
![Page 43: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/43.jpg)
tablas hash abiertas
• vamos buscando por la lista
pos = hash(valor)
while (tabla[pos] está ocupada)
pos = siguiente(pos);
• puede llenarse la tabla
diccionarios 43
![Page 44: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/44.jpg)
tablas hash abiertas
• prueba lineal
pos = hash(valor);
for (int i= 0; i < tabla.length; i++)
if (tabla[pos + i] == null)
return pos + i;
• problema: se forman ristras de valores
– en cuanto un valor cae en la ristra hay que recorrerla hasta el final
diccionarios 44
![Page 45: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/45.jpg)
tablas hash abiertas
• prueba cuadrática
pos = hash(valor);
for (int i= 0; i < tabla.length; i++)
if (tabla[pos + i * i] == null)
return pos + i * i;
• se forman ristras de valores
– pero son ristras llenas de agujeros y es menos “probable” que un valor caiga en la trampa
diccionarios 45
![Page 46: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/46.jpg)
tablas hash abiertas
• prueba con segundo hash – pos = hash(valor);
– h2= hash_alternativo(valor);
– for (int i= 0; i < tabla.length; i++)
– if (tabla[pos + i * h2] == null)
– return pos + i * h2;
• se forman ristras de valores – pero son ristras llenas de agujeros
y es aún menos “probable” que un valor caiga en la trampa
diccionarios 46
![Page 47: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/47.jpg)
tablas hash abiertas - complejidad
• si la tabla está poco llena
– hay pocas colisiones o se resuelven deprisa
– algoritmos O(1)
• si la tabla se llena
– hay muchas colisiones y exigen recorrer la tabla
– algoritmos O(n)
• o sea, o gastamos RAM o gastamos tiempo
diccionarios 47
![Page 48: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/48.jpg)
biblioteca de java
• interface Map • class HashMap implements Map
– diccionario con listas para colisiones – cuando la tabla se llena,
se duplica la tabla y se reubican valores en nuevas listas
– “garantiza” O(1)
• class TreeMap implements Map – diccionario con árbol de búsqueda – operaciones O(log n) – ventaja: mantiene los datos ordenados
diccionarios 48
![Page 49: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/49.jpg)
tiempos tablas hash
• factor de carga = 60%
diccionarios 49
N listas abierta HashMap TreeMap
1.000 52.957 51.725 58.705 67.736
2.000 51.726 52.136 64.041 82.925
5.000 43.104 45.157 61.168 83.336
10.000 50.905 43.925 43.105 124.388
20.000 44.746 44.747 23.399 92.367
50.000 34.894 34.484 27.095 102.630
100.000 38.589 39.410 28.325 169.134
200.000 45.567 44.336 38.999 59.936
500.000 50.494 48.442 35.536 72.662
![Page 50: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/50.jpg)
tiempos tablas hash
diccionarios 50
en función del factor de carga
carga abierta listas 0,50 33.252 113.304 0,60 36.947 49.262 0,70 34.894 59.115 0,80 39.821 53.367 0,90 59.935 66.505 0,95 82.514 69.788 0,96 97.703 46.799 0,97 101.398 51.314 0,98 275.459 55.420 0,99 236.049 52.547 1,00 56.651 2,00 101.398 5,00 63.630
10,00 70.199
![Page 51: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/51.jpg)
complejidad put get remove
arrays O(1) O(n) O(n)
arrays ordenados O(n) O(log n) O(n)
árbol binario O(log n) O(log n) O(log n)
hash con listas O(1) si k > N O(N) si k << N
hash abierto carga << 1
O(1)
HashMap (con rehash)
O(1)
TreeMap O(log n)
diccionarios 51
![Page 52: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/52.jpg)
conclusiones
• Se puede hacer de muchas formas
– unas son más rápidas que otras
• En la práctica tendremos que
– elegir algoritmos según nos convenga
– medir, medir y medir
diccionarios 52
![Page 53: 022_diccionarios](https://reader034.vdocuments.co/reader034/viewer/2022042616/55cf966c550346d0338b5b96/html5/thumbnails/53.jpg)
optimización de programas
• como regla general
– el 95% de los recursos de un programa
– los consume el 5% del código
1. identifique ese 5%
2. optimice ese 5%
1. elija un algoritmo adecuado
2. refactorice el código para acelerarlo al máximo
• variables temporales para evitar cálculos repetidos
• reutilización de objetos para evitar new X()
diccionarios 53