(Cuándo) es la búsqueda de tabla hash O (1)?

71

A menudo se dice que la búsqueda de tabla hash funciona en tiempo constante: se calcula el valor hash, lo que le da un índice para una búsqueda de matriz. Sin embargo, esto ignora las colisiones; en el peor de los casos, todos los elementos caen en el mismo depósito y el tiempo de búsqueda se vuelve lineal ( ).Θ(n)

¿Existen condiciones en los datos que pueden hacer que la búsqueda de tablas hash sea realmente ? ¿Es eso solo en promedio, o puede una tabla hash tener O ( 1 ) peor búsqueda?O(1)O(1)

Nota: vengo desde la perspectiva de un programador aquí; cuando almaceno datos en una tabla hash, casi siempre son cadenas o algunas estructuras de datos compuestos, y los datos cambian durante la vida útil de la tabla hash. Entonces, aunque aprecio las respuestas sobre los hashes perfectos, son lindos pero anecdóticos y no prácticos desde mi punto de vista.

Seguimiento de PS: ¿Para qué tipo de datos son las operaciones de tabla hash O (1)?

Gilles 'SO- deja de ser malvado'
fuente
3
¿Se puede vivir con tiempo de acceso amortizado? En general, el rendimiento de la tabla hash dependerá en gran medida de la sobrecarga de tablas hash dispersas que esté preparado para tolerar y de cómo se distribuyan los valores hash reales. O(1)
Raphael
55
Ah, por cierto: puede evitar el comportamiento lineal del peor de los casos utilizando árboles de búsqueda (equilibrados) en lugar de listas.
Raphael
1
@Raphael Estaría muy interesado en una respuesta que explique (en líneas generales) cuándo puedo contar con amortizado y cuándo no puedo. En cuanto a cómo se distribuyen los valores hash, esa es realmente mi pregunta: ¿cómo puedo saberlo? Sé que se supone que las funciones hash distribuyen bien los valores; pero si siempre lo hicieran, el peor de los casos nunca se alcanzaría, lo que no tiene sentido. O(1)
Gilles 'SO- deja de ser malvado'
1
También tenga cuidado con la optimización prematura; para datos pequeños (varios miles de elementos), a menudo he visto que los árboles binarios balanceados superan a las tablas hash debido a una sobrecarga menor (las comparaciones de cadenas son mucho más baratas que los hashes de cadenas). O(logn)
isturdy
Continuemos esta discusión en el chat .
Raphael

Respuestas:

41

Hay dos configuraciones en las que puede obtener peor de los casos.O(1)

  1. Si su configuración es estática, entonces el hashing FKS obtendrá las garantías peor de los casos . Pero como indicó, su configuración no es estática.O(1)

  2. Si usa el hash de Cuckoo, las consultas y eliminaciones son peor de los casos, pero la inserción es solo O ( 1 ) esperada. El hash de cuco funciona bastante bien si tiene un límite superior en el número total de inserciones y establece que el tamaño de la tabla sea aproximadamente un 25% más grande.O(1)O(1)

Hay más información aquí .

Suresh
fuente
3
¿Podrías expandirte en FKS y Cuckoo? Ambos términos son nuevos para mí.
Gilles 'SO- deja de ser malvado'
1
¿Qué pasa con el hashing dinámico perfecto? Tiene búsquedas en el peor de los casos y O ( 1 ) inserción y eliminación amortizadas. ( citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.30.8165 )O(1)O(1)
Joe
2
FKS son las iniciales de (Fredman, Komlós, Szemerédi) y Cuckoo es el nombre de una especie de novia. Es útil para este tipo de picadillo, porque los polluelos de cuco empujan los huevos del nido. Esto se parece un poco a cómo funciona este método hasing.
uli
1
@Suresh: ¿En serio? Pensé que necesitabas funciones independientes de , que siempre asociaba con la necesidad de expansores. Estoy corregido. Eliminaré mi comentario en un momento. logn
Louis
1
Para hacer un comentario más útil sobre esta respuesta, como señala @Suresh, el hash de cuco funcionará bien sin las sofisticadas (y grandes) funciones de hash utilizadas para analizarlo teóricamente.
Louis
21

Esta respuesta resume partes de TAoCP Vol. 3, Cap. 6.4.

VnAmh:V[0..M)M|V|α=nmAm=MmMm

hO(1)

[0..M)CnSCnU

Encadenamiento

nm

CnS1+α2 and CnU1+α22.

Sondeo lineal

v

h(v),h(v)1,,0,m1,,h(v)+1
vα1
CnS12(1+11α) and CnU12(1+(11α)2).
α<0.75

Hashing doble

M

CnS1αln(11α) and CnU11α.

Tenga en cuenta que eliminar elementos de tablas y extenderlas tiene diferentes grados de dificultad para los métodos respectivos.

O(1)αh


h
Hashtable

Rafael
fuente
10

S{0,1,2,...,n}O(1)O(1)lSlxxSO(|l|)SO(|S|)O(|l|+|S|)O(|l||S|)O(log(|l|)|S|)O(|l|)l

O(|l|)

lUNSUxSllh:U{true,false}hh(x)=falsexUylh(y)=trueO(|l|)O(|U|)

lO(|U|)O(|1|)O(|U|)

Uh

Patrick87
fuente
O(|l|)O(|S|)O(|l||S|)
hh:U{false,true}h
@Gilles Básicamente se usa como una tabla de búsqueda para la membresía de la lista. Cuando tiene una función hash perfecta con un inverso conocido y barato, en lugar de almacenar la cosa en sí, solo necesita almacenar 1 bit (ya sea que se haya agregado la cosa con el hash único). Si las colisiones son posibles, creo que hacer esto se conoce como un filtro de Bloom, pero en cualquier caso puede proporcionar un "no" definitivo a la cuestión de la membresía, que todavía es útil en muchos escenarios.
Patrick87
9

O(1)

O(1)O(1)O(1)O(1)

Nicholas Meyer
fuente
Una función hash perfecta sería perfecta, pero ¿cómo obtengo una? ¿Cuánto me costará? ¿Y cómo sé cuál es el número máximo o esperado de colisiones?
Gilles 'SO- deja de ser malvado'
2
@Gilles, una función hash perfecta es cualquier función que produzca un hash único para todas las entradas posibles. Si sus posibles entradas son finitas (y únicas), esto es fácil de hacer.
Rafe Kettler
1
@RafeKettler Mis entradas son típicamente cadenas o estructuras de datos compuestos, y generalmente agrego y elimino entradas a medida que evolucionan mis datos. ¿Cómo hago un hash perfecto para esto?
Gilles 'SO- deja de ser malvado'
44
Sí, pero ese es el punto. Una función hash perfecta determinista no existe si el dominio es mayor que el rango.
Suresh
@Suresh: si se le permite elegir una nueva función hash y aumentar el tamaño de la tabla cada vez que hay una colisión, siempre puede encontrar una función hash (determinista) que, para los datos que ya están en la tabla más la nueva elemento que está intentando insertar: no tiene colisiones (es "perfecto"). Es por eso que el hashing dinámico perfecto elige periódicamente una nueva función hash aleatoria.
David Cary