web-dev-qa-db-fra.com

Comment le hachage a-t-il un temps de recherche o(1)?

Lorsque nous utilisons un HashTable pour stocker des données, il est dit que la recherche prend o(1) temps. Je suis confus, quelqu'un peut-il expliquer?

56
algo-geeks

Eh bien, c'est un petit petit mensonge - cela peut prendre plus de temps, mais ce n'est généralement pas le cas.

Fondamentalement, une table de hachage est un tableau contenant toutes les clés sur lesquelles effectuer la recherche. La position de chaque clé dans le tableau est déterminée par la fonction de hachage , qui peut être n'importe quelle fonction qui mappe toujours la même entrée à la même sortie. Nous supposerons que la fonction de hachage est O (1).

Donc, lorsque nous insérons quelque chose dans la table de hachage, nous utilisons la fonction de hachage (appelons-la h ) pour trouver l'emplacement où la mettre, et mettons là-bas. Maintenant, nous insérons une autre chose, le hachage et le stockage. Et un autre. Chaque fois que nous insérons des données, il faut O(1) temps pour les insérer (puisque la fonction de hachage est O (1).

La recherche de données est la même. Si nous voulons trouver une valeur, x , nous n'avons qu'à trouver h (x), qui nous indique où x se trouve dans la table de hachage. Nous pouvons donc rechercher n'importe quelle valeur de hachage dans O(1) également.

Maintenant au mensonge: ce qui précède est une théorie très agréable avec un problème: que se passe-t-il si nous insérons des données et qu'il y a déjà quelque chose à cette position du tableau? Il n'y a rien qui garantit que la fonction de hachage ne produira pas la même sortie pour deux entrées différentes (sauf si vous avez une fonction de hachage parfaite , mais celles-ci sont difficiles à produire). Par conséquent, lorsque nous insérons, nous devons adopter l'une des deux stratégies suivantes:

  • Stockez plusieurs valeurs à chaque endroit du tableau (par exemple, chaque emplacement de tableau a une liste liée). Maintenant, lorsque vous effectuez une recherche, il reste O(1) pour arriver au bon endroit dans le tableau, mais potentiellement une recherche linéaire dans une liste chaînée (espérons-le courte). Cela s'appelle "enchaînement séparé".
  • Si vous trouvez que quelque chose est déjà là, hachez à nouveau et trouvez un autre emplacement. Répétez jusqu'à ce que vous trouviez un endroit vide et placez-le là. La procédure de recherche peut suivre les mêmes règles pour rechercher les données. Il reste maintenant O(1) pour arriver au premier emplacement, mais il y a une recherche linéaire potentiellement (espérons-le courte) pour rebondir autour de la table jusqu'à ce que vous trouviez les données que vous recherchez. Ceci est appelé "adressage ouvert".

Fondamentalement, les deux approches sont toujours principalement O(1) mais avec une séquence linéaire courte, espérons-le. Nous pouvons supposer dans la plupart des cas, il s'agit de O (1). Si la table de hachage est trop pleine, ces recherches linéaires peuvent devenir de plus en plus longues, puis il est temps de "re-hacher", ce qui signifie créer une nouvelle table de hachage d'un beaucoup plus grande taille et réinsérez toutes les données.

111
mgiuca

La recherche prend O(1) fois s'il n'y a pas de collisions dans la table de hachage, donc il est incorrect pour sya que la recherche dans une table de hachage prenne O(1) ou à temps constant.

Voir comment fonctionne Hashtable sur MSDN?

[~ # ~] modifier [~ # ~]

mgiuca l'explique magnifiquement et j'ajoute juste une technique de prévention de la corrosion supplémentaire qui s'appelle le chaînage.

Dans cette technique, nous maintenons une liste de liens de valeurs à chaque emplacement, donc lorsque vous avez une collision, votre valeur sera ajoutée à la liste de liens à cette position, donc lorsque vous recherchez une valeur, il peut y avoir un scénario dont vous avez besoin pour rechercher la valeur dans toute la liste de liens, dans ce cas, la recherche ne sera pas une opération O(1)).

5
TalentTuner