Mon implémentation actuelle d'une table de hachage utilise le sondage linéaire et maintenant je veux passer au sondage quadratique (et plus tard au chaînage et peut-être au double hachage). J'ai lu quelques articles, tutoriels, wikipédia, etc ... Mais je ne sais toujours pas exactement ce que je devrais faire.Passer du sondage linéaire au sondage quadratique (collisions de hachage)
Linear Sondage, fondamentalement, a un pas de 1 et c'est facile à faire. Lors de la recherche, l'insertion ou la suppression d'un élément de la table de hachage, je dois calculer un hachage et que je fais:
index = hash_function(key) % table_size;
Ensuite, lors de la recherche, l'insertion ou la suppression boucle I à la table jusqu'à ce que je trouve un seau libre, comme ceci:
do {
if(/* CHECK IF IT'S THE ELEMENT WE WANT */) {
// FOUND ELEMENT
return;
} else {
index = (index + 1) % table_size;
}
while(/* LOOP UNTIL IT'S NECESSARY */);
Quant à quadratique Sonder, je pense que ce que je dois faire est de changer la façon dont la taille de l'étape « index » est calculé, mais c'est ce que je ne comprends pas comment je devrais le faire. J'ai vu divers morceaux de code, et tous sont quelque peu différents.
En outre, j'ai vu quelques implémentations de sondage quadratique où la fonction de hachage est modifiée pour accommoder cela (mais pas tous). Est-ce que ce changement est vraiment nécessaire ou est-ce que je peux éviter de modifier la fonction de hachage et d'utiliser Quadratic Probing? Après avoir lu tout ce qui a été souligné par Eli Bendersky ci-dessous, je pense que j'ai eu l'idée générale. Voilà une partie du code à http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_hashtable.aspx:
15 for (step = 1; table->table[h] != EMPTY; step++) {
16 if (compare (key, table->table[h]) == 0)
17 return 1;
18
19 /* Move forward by quadratically, wrap if necessary */
20 h = (h + (step * step - step)/2) % table->size;
21 }
Il y a 2 choses que je ne comprends pas ... On dit que se fait généralement à l'aide du second degré de sondage c(i)=i^2
. Cependant, dans le code ci-dessus, il fait quelque chose de plus comme c(i)=(i^2-i)/2
J'étais prêt à mettre en œuvre sur mon code, mais je voudrais simplement faire:
index = (index + (index^index)) % table_size;
... et non:
index = (index + (index^index - index)/2) % table_size;
Si quoi que ce soit, je le ferais:
index = (index + (index^index)/2) % table_size;
... parce que je l'ai vu d'autres exemples de code plonger par deux. Bien que je ne comprends pas pourquoi ...
1) Pourquoi soustraire l'étape?
2) Pourquoi est-ce qu'il plonge par 2?
garder à l'esprit que du second degré de sondage est efficace que si la taille de la table est le premier et le facteur de charge est <0,5; voir http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_hashtable.aspx pour un aperçu des différentes stratégies de résolution de collision – Christoph
@Cristoph: cette affirmation n'est pas tout à fait juste. Si la taille de la table est un nombre premier, alors il est garanti de fonctionner correctement si le facteur de charge est <0,5; mais ce n'est pas vrai que c'est le seul cas où le sondage quadratique fonctionne. Par exemple, il peut aussi être efficace avec une taille de table de puissance de 2 et un facteur de charge arbitraire (voir ma réponse). –
@Mathew: il y a une différence entre «travailler» et «travailler efficacement»; Si le facteur de charge est trop élevé, le clustering (secondaire) pourrait devenir un problème à nouveau – Christoph