Je sais que je peux utiliser un dictionnaire Je sais que je peux obtenir le prochain élément le plus élevé (ou le plus bas) d'un Puis-je utiliser le est le mot Remarque: le cas d'utilisation est une sorte de file d'attente prioritaire ou de la file d'attente ordonnée. Aucune source ouverte n'est autorisée pour cela (doit être du code-gratter ou déjà dans le cadre .NET 3.5). P> code> et récupérer un élément arbitraire dans O (1) heure. P>
triodictionnaire code> strong>
in o (1) heure. Mais si je voulais supprimer la valeur tkey code> S
icomparable code>) dans le type code> code>? p>
.nfirst ( ) code> strong>
méthode pour récupérer la plus petite clé? Et quelle est sa complexité? Fonctionnera-t-il dans O (1), O (log n) ou O (n) heure? P>
triodictionnaire code> la structure de données correcte pour cela? p>
6 Réponses :
Si vous avez un triodictionnaire code> ou
sortedlist code>, vous pouvez utiliser
.First () code> (ou
dict.keys [0] code> pour
tritedlist code>) Sinon, vous pouvez le faire:
dict[dict.Keys.Min()]
Je pense que l'objectif serait d'obtenir O (log n) ou mieux. Il y aura beaucoup d'articles dans la collection et ils seront toujours extraits la plus petite clé en premier.
Ensuite, vous devez utiliser un triodictionnaire code> (ou
sortidlist code>). Il suffit de garder votre insertion et votre suppression des coûts à l'esprit aussi.
Pourquoi ne conservez-vous pas une liste triée séparée des touches afin que vous puissiez toujours obtenir l'élément avec la plus petite clé simplement en faisant dict [keyliste [0]] code>. p>
TritedList et typeDictionnaire sont implémentés en interne comme des arbres de recherche binaires et pouvaient idéalement vous donner des performances O (log n) pour un min (nécessite de marcher dans l'arbre, mais de ne pas énumérer toute la liste). Cependant, l'utilisation de LINQ pour effectuer que MIN énumérera probablement toute la liste. P>
Je considérerais un Skip List comme une meilleure structure de données alternative. P>
Est-ce que .NET a une implémentation de la liste de skip natif?
@RObert, malheureusement non - vous devriez la mettre en œuvre vous-même (ou utiliser une implémentation open source, mais vous avez dit que ce n'est pas une option.) Toutefois, l'algorithme de base n'est pas particulièrement difficile à mettre en œuvre et que l'article de MSDN que j'ai relié aux promenades à travers le noyau.
Linq utiliserait getenumerator () code> pour récupérer le premier élément (O (journal n)), pas
min () code>.
@Marcelo, si .First () (AKA: Getenumerator) retournerait la valeur minimale dépend de l'ordre de tri de la sélection
Min nécessite énumérer toute la liste car elle ne peut pas savoir que c'est trié. Linq a une méthode .First ().
La seule chose qui me dérange des listes de saut serait leur consommation de mémoire. Trop énorme ..
@nawfal Skip Listez la liste pire des cas est O (n log n), mais le cas attendu (équilibré) est O (n). La mémoire de négociation pour la vitesse est souvent une option acceptable. Cependant, comme pour toutes les structures de données, ce ne sera pas le choix idéal pour chaque scénario possible.
@Hemp je reçois votre point de vue, il s'agit d'une analyse coûts-avantages et des listes de saut parfois font la coupe. Ce que je veux dire, c'est que je ne saute pas sur le train "plus rapide - le meilleur" quand je sais que cela a un coût. Ce qui me fait donner une double pensée avant que je n'utilise que c'est le fait qu'il consomme beaucoup de mémoire par entrée, donc je sais que cela pourrait avoir une limite à la quantité de personnes pouvant être tenues. Ce n'est pas seulement sur la mise à l'échelle, mais aussi combien il peut pratiquement tenir sans être trop à la mémoire. Dans une liste de sauts, chaque entrée contient un tableau d'autres références de nœuds, le plus grand fabricant de différence.
SortieListe n'utilise pas une BST dans les coulisses. C'est juste un tableau trié qui utilise une recherche binaire de recherche.
@ Dev27 Vous êtes correct, je ne sais pas pourquoi je pensais que les deux structures utilisées BSTS. Le temps nécessaire pour supprimer les enregistrements dans les deux structures varie de manière significative. Dans le cas de la question de l'OP, la fonction de retrait de la liste de tri requiert deux copies complètes de la matrice, ce qui n'est certainement pas génial.
trierddictionary.getenumerator est indiqué comme ayant O (log n) temps - donc d'abord () devrait suivre la poursuite. P>
@HEMP: N'est-ce pas ce que le triodictionnaire code> fait?
@ROBERT: Il trie en utilisant IComparable - comment cette icomparable est mise en œuvre détermine l'ordre de tri. Puisque vous possédez la structure de données dans ce cas, tout irait bien.
Puisque vous avez seulement mentionné avoir des valeurs et ne pas les définir, Vous pouvez utiliser une liste simple, trier à l'avance, puis accéder à n'importe quelle valeur, par ordre, dans O (1). P>
Avec une collection non formée, obtenir l'élément le plus élevé ou le plus bas est O (n) car l'un des éléments pourrait être le plus haut ou le plus bas pour que vous puissiez regarder chacun. Si vous voulez le faire rapidement (O (1)), vous avez besoin d'une structure de données triée afin que vous puissiez déduire les positions relatives des valeurs en fonction de leur emplacement. P>
Robert, dans un dictionnaire trié, vous devez généralement loger2n pour obtenir un élément min, ce n'est pas O (1). Les tas offrent O (1) accès à Min (ou max).
@Best: Je n'ai pas dit
min code> est O (1). Lisez la question à nouveau: l'élément suivant i> est O (1)
Suivant le plus haut / le plus bas i> (dans un sous-ensemble), prédécesseur / successeur d'un élément ne sont pas non plus O (1).