web-dev-qa-db-fra.com

Comment choisir entre une table de hachage et un Trie (arbre de préfixe)?

Donc, si je dois choisir entre une table de hachage ou un arbre de préfixe, quels sont les facteurs discriminants qui m'amèneraient à choisir l'un plutôt que l'autre. De mon propre point de vue naïf, il semble que l'utilisation d'un trie ait un surcoût supplémentaire car il n'est pas stocké sous forme de tableau mais qu'en termes d'exécution (en supposant que la clé la plus longue est le mot anglais le plus long), cela peut être essentiellement = O(1) (par rapport à la limite supérieure). Peut-être que le mot anglais le plus long est de 50 caractères?

Les tables de hachage sont une recherche instantanée ne fois que vous obtenez l'index. Le hachage de la clé pour obtenir l'index semble cependant pouvoir facilement prendre près de 50 étapes.

Quelqu'un peut-il me fournir une perspective plus expérimentée à ce sujet? Merci!

127
Justin Bozonier

Avantages des essais:

Les bases:

  • Prévisible O(k) temps de recherche où k est la taille de la clé
  • La recherche peut prendre moins de k temps si elle n'est pas là
  • Prend en charge la traversée ordonnée
  • Pas besoin d'une fonction de hachage
  • La suppression est simple

Nouvelles opérations:

  • Vous pouvez rechercher rapidement des préfixes de clés, énumérer toutes les entrées avec un préfixe donné, etc.

Avantages de la structure liée:

  • S'il existe de nombreux préfixes communs, l'espace dont ils ont besoin est partagé.
  • Les essais immuables peuvent partager la structure. Au lieu de mettre à jour un trie en place, vous pouvez en créer un nouveau qui n'est différent que le long d'une branche, pointant ailleurs dans l'ancien trie. Cela peut être utile pour la simultanéité, plusieurs versions simultanées d'une table, etc.
  • Un tri immuable est compressible. Autrement dit, il peut également partager la structure sur les suffixes , par hachage.

Avantages des tables de hachage:

  • Tout le monde connaît les tables de hachage, non? Votre système aura déjà une implémentation Nice bien optimisée, plus rapide que la plupart des essais.
  • Vos clés n'ont pas besoin d'avoir une structure spéciale.
  • Plus économe en espace que la structure évidente du tri lié (voir les commentaires ci-dessous)
113
Darius Bacon

Tout dépend du problème que vous essayez de résoudre. Si tout ce que vous devez faire est des insertions et des recherches, optez pour une table de hachage. Si vous devez résoudre des problèmes plus complexes tels que les requêtes liées aux préfixes, un trie pourrait être la meilleure solution.

45
Adam Rosenfield

Tout le monde connaît la table de hachage et ses utilisations, mais ce n'est pas exactement le temps de recherche constant, cela dépend de la taille de la table de hachage, de la complexité de calcul de la fonction de hachage.

La création d'énormes tables de hachage pour une recherche efficace n'est pas une solution élégante dans la plupart des scénarios industriels où même une petite latence/évolutivité est importante (par exemple: trading haute fréquence). Vous devez également vous soucier des structures de données à optimiser pour l'espace qu'il occupe en mémoire afin de réduire les erreurs de cache.

Un très bon exemple où trie correspond mieux aux exigences est le middleware de messagerie. Vous avez un million d'abonnés et d'éditeurs de messages dans différentes catégories (en termes JMS - Sujets ou échanges), dans ce cas, si vous souhaitez filtrer les messages en fonction des sujets (qui sont en fait des chaînes), vous ne voulez certainement pas créer de table de hachage pour le million d'abonnements avec des millions de sujets. Une meilleure approche consiste à stocker les sujets dans un tri, donc lorsque le filtrage est effectué en fonction de la correspondance des sujets, sa complexité est indépendante du nombre de sujets/abonnements/éditeurs (dépend uniquement de la longueur de la chaîne). Je l'aime parce que vous pouvez être créatif avec cette structure de données pour optimiser les besoins en espace et donc avoir moins de cache manquant.

26
user179156

Utilisez un arbre:

  1. Si vous avez besoin de la fonction de saisie semi-automatique
  2. Trouvez tous les mots commençant par "a" ou "hache" ainsi de suite.
  3. Un arbre suffixe est une forme spéciale d'arbre. Les arbres de suffixes ont toute une liste d'avantages que le hachage ne peut pas couvrir.
8
Dr.Sai

Il y a quelque chose que je n'ai vu personne mentionner explicitement qu'il est important de garder à l'esprit. Les tables de hachage et les essais de différents types auront généralement des opérations O(k), où k est la longueur de la chaîne en bits (ou de manière équivalente en caractères).

Cela suppose que vous disposez d'une bonne fonction de hachage. Si vous ne voulez pas que "ferme" et "animaux de ferme" hachent à la même valeur, alors la fonction de hachage devra utiliser tous les bits de la clé, et donc le hachage "animaux de ferme" devrait prendre environ deux fois plus de temps que "ferme" (sauf si vous êtes dans une sorte de scénario de hachage continu, mais il existe également des scénarios d'économie d'opérations similaires avec des essais). Et avec un essai à la vanille, il est clair pourquoi l'insertion "d'animaux de ferme" prendra environ deux fois plus de temps que "ferme". À long terme, c'est également vrai pour les essais compressés.

2
user3391564

L'insertion et la recherche sur un trie sont linéaires avec la longueur de la chaîne d'entrée O (s).

Un hachage vous donnera un O(1) pour la recherche et l'insertion, mais vous devez d'abord calculer le hachage sur la base de la chaîne d'entrée qui est à nouveau O (s).

En conclusion, la complexité temporelle asymptotique est linéaire dans les deux cas.

Le trie a un peu plus de frais généraux du point de vue des données, mais vous pouvez choisir un trie compressé qui vous mettra plus ou moins sur un lien avec la table de hachage.

Pour rompre le lien, posez-vous cette question: dois-je rechercher uniquement les mots complets? Ou dois-je retourner tous les mots correspondant à un préfixe? (Comme dans un système de saisie de texte prédictif). Pour le premier cas, optez pour un hachage. C'est un code plus simple et plus propre. Plus facile à tester et à entretenir. Pour un cas d'utilisation plus élaboré où les préfixes ou les suffixes sont importants, optez pour un trie.

Et si vous le faites juste pour le plaisir, la mise en œuvre d'un trie mettrait un dimanche après-midi à bon escient.

2
Visiedo

HashTable l'implémentation est peu encombrante par rapport à l'implémentation de base Trie. Mais avec des cordes, la commande est nécessaire dans la plupart des applications pratiques. Mais HashTable perturbe totalement l'ordre lexographique. Maintenant, si votre application effectue des opérations basées sur l'ordre lexographique (comme la recherche partielle, toutes les chaînes avec le préfixe donné, tous les mots dans l'ordre trié), vous devez utiliser Tries. Pour la recherche uniquement, HashTable doit être utilisé (car sans doute, il donne un temps de recherche minimum).

P.S.: Autre que ceux-ci, Ternary Search Trees (TSTs)) serait un excellent choix. Son temps de recherche est supérieur à HashTable, mais il est efficace dans toutes les autres opérations. En outre, son espace est plus efficace que les essais.

2
Jay Jodiwal