On dit souvent que la recherche de table de hachage fonctionne à temps constant: vous calculez la valeur de hachage, ce qui vous donne un index pour une recherche de tableau. Pourtant, cela ignore les collisions; dans le pire des cas, chaque élément arrive dans le même compartiment et le temps de recherche devient linéaire ( ).
Y a-t-il des conditions sur les données qui peuvent rendre la recherche dans une table de hachage vraiment ? Est-ce seulement en moyenne, ou une table de hachage peut-elle avoir la recherche pire des cas?O ( 1 )
Remarque: je viens du point de vue d'un programmeur ici; Lorsque je stocke des données dans une table de hachage, ce sont presque toujours des chaînes ou des structures de données composites, et les données changent pendant la durée de vie de la table de hachage. Ainsi, bien que j'apprécie les réponses concernant les hachages parfaits, elles sont mignonnes mais anecdotiques et peu pratiques de mon point de vue.
Suivi PS: Pour quel type de données les opérations de table de hachage sont-elles O (1)?
la source
Réponses:
Il existe deux paramètres sous lesquels vous pouvez obtenir pires cas.O(1)
Si votre configuration est statique, le hachage FKS vous apportera les garanties plus défavorables . Mais comme vous l'avez indiqué, votre réglage n'est pas statique.O(1)
Si vous utilisez le hachage Cuckoo, les requêtes et les suppressions sont considérées comme étant le cas le plus défavorable de , mais l'insertion n'est attendue que de . Le hachage de coucou fonctionne assez bien si vous avez une limite supérieure sur le nombre total d'insertions et si vous définissez une taille de table environ 25% plus grande.O ( 1 )O(1) O(1)
Il y a plus d'informations ici .
la source
Cette réponse résume des parties de TAoCP Vol 3, Ch 6.4.
Supposons que nous ayons un ensemble de valeurs , que nous voulons stocker dans un tableau de taille . Nous employons une fonction de hachage ; typiquement,. Nous appelons le facteur de charge de . Ici, nous supposerons le naturel ; dans les scénarios pratiques, nous avons , cependant, et doivent cartographier jusqu'à nous.n A m h : V → [ 0 .. M ) M ≪ | V | α = nV n A m h:V→[0..M) M≪|V| Am=Mm≪Mmα=nm A m=M m≪M m
La première observation est que même si présente des caractéristiques uniformes¹, la probabilité que deux valeurs aient la même valeur de hachage est élevée; c’est essentiellement un exemple du fameux paradoxe des anniversaires . Par conséquent, nous devrons généralement faire face à des conflits et abandonner tout espoir de pire des cas.O ( 1 )h O(1)
Qu'en est-il du cas moyen, cependant? Supposons que chaque clé de se produit avec la même probabilité. Le nombre moyen d'entrées vérifiées (recherche réussie) resp. (recherche infructueuse) dépend de la méthode de résolution de conflit utilisée.C S n C U n[0..M) CSn CUn
Chaînage
Chaque entrée de tableau contient (un pointeur sur l'en-tête de) une liste liée. C'est une bonne idée car la longueur de liste attendue est petite ( ), même si la probabilité d'avoir des collisions est élevée. Au final, nous obtenons Cela peut être légèrement amélioré en stockant les listes (partiellement ou complètement) dans la table. C S n ≈1+αnm
Palpage linéaire
Lorsque vous insérez (ou cherchez une valeur) , vérifiez les positions dans cet ordre jusqu'à une position vide (resp. ) est trouvé. L'avantage est que nous travaillons localement et sans structures de données secondaires; cependant, le nombre d'accès moyens diverge pour : Pour , toutefois, les performances sont comparables à celles du chaînage².v
Double hachage
Similaire à sonder linéaire mais la taille de l' étape de recherche est commandée par une seconde fonction de hachage qui est premier à . Aucune dérivation formelle n'est donnée, mais des observations empiriques suggèrent que Cette méthode a été adaptée par Brent. Cette variante amortit les coûts d’insertion accrus par des recherches moins coûteuses.C S n ≈ 1M
Notez que le retrait d'éléments des tables et leur extension présentent des difficultés variables pour les méthodes respectives.
En bout de ligne, vous devez choisir une implémentation qui s'adapte bien à vos cas d'utilisation typiques. Le temps d'accès attendu dans est possible s'il n'est pas toujours garanti. En fonction de la méthode utilisée, maintenir low est essentiel; vous devez faire un compromis entre le temps d'accès (prévu) et les frais généraux. Un bon choix pour est aussi central, évidemment.O(1) hα h
1]h
Etant donné queles programmeurs nonavertisarbitrairementmuetspeuvent fournir , toute hypothèse concernant sa qualité n’est pas pratique dans la pratique. 2] Notez comment cela coïncide avec les recommandations d'utilisation de Java .Hashtable
la source
Une fonction de hachage parfaite peut être définie comme une fonction injective d’un ensemble à un sous-ensemble des entiers . Si une fonction de hachage parfaite existe pour vos données et vos besoins de stockage, vous pouvez facilement obtenir le comportement . Par exemple, vous pouvez obtenir la performance d'une table de hachage pour la tâche suivante: étant donné un tableau d'entiers et un ensemble d'entiers, déterminer si contient pour chaque . Une étape de pré-traitement impliquerait de créer une table de hachage dans , puis de vérifier chaque élément de rapport à lui dansS {0,1,2,...,n} O(1) O(1) l S l x x∈S O(|l|) S O(|S|) . Au total, c'est . Une implémentation naïve utilisant la recherche linéaire pourrait être ; en utilisant la recherche binaire, vous pouvez faire (notez que cette solution est un espace , car la table de hachage doit mapper des entiers distincts de vers des segments distincts).O(|l|+|S|) O(|l||S|) O(log(|l|)|S|) O(|l|) l
EDIT: Pour clarifier la manière dont la table de hachage est générée dans :O(|l|)
La liste contient des nombres entiers à partir d' un ensemble fini , le cas échéant avec des répétitions, et . Nous voulons déterminer si est dans . Pour ce faire, nous pré-calculons une table de hachage pour les éléments de : une table de recherche. La table de hachage encodera une fonction . Pour définir , on suppose d' abord pour tout . Ensuite, parcourez linéairement les éléments de en définissant . Cela prend temps etl U⊂N S⊆U x∈S l l h:U→{true,false} h h(x)=false x∈U y l h(y)=true O(|l|) O(|U|) espace.
Notez que mon analyse initiale supposait que contenait au moins éléments distincts. S'il contient moins d'éléments distincts (par exemple, ), l'espace requis peut être supérieur (même s'il ne s'agit pas de plus de ).l O(|U|) O(|1|) O(|U|)
EDIT2: La table de hachage peut être stockée sous la forme d'un tableau simple. La fonction de hachage peut être la fonction d'identité sur . Notez que la fonction identité est trivialement une fonction de hachage parfaite. est la table de hachage et code une fonction séparée. Je suis confuse / confuse dans certains de ce qui précède, mais je vais essayer de l'améliorer bientôt.U h
la source
Une fonction de hachage parfaite donnera pire des recherches.O(1)
De plus, si le nombre maximal de collisions possible est , on peut dire que la recherche dans la table de hachage est dans le pire des cas. Si le nombre de collisions attendu est , la recherche dans la table de hachage peut être considérée comme étant dans le cas moyen.O ( 1 ) O ( 1 ) O ( 1 )O(1) O(1) O(1) O(1)
la source