n log n > n
- mais cela ressemble à une relation pseudo-linear
. Si n=1 billion
, Connectez-vous ~ 30;
Donc n log n
Sera 30 billion
, Qui est 30 X n
, Ordre de n
. Je me demande si cette différence de complexité temporelle entre n log n and n
Est significative dans la vie réelle.
Par exemple: un quick select
Lors de la recherche du kème élément dans un tableau non trié est O(n)
à l'aide de l'algorithme quickselect.
Si je trie le tableau et trouve le kième élément, c’est O(n log n)
. Pour trier un tableau avec les éléments 1 trillion
, Je serais plus lent 60 times
Si je faisais quicksort
et index it
.
L’objectif principal de la notation Big-O est de vous permettre de faire les estimations comme celles que vous avez faites dans votre message et de décider vous-même si le fait de coder pour un algorithme généralement plus perfectionné vaut la peine que vous passiez à des cycles de CPU supplémentaires. acheter avec cette amélioration du code. Selon les circonstances, vous pouvez obtenir une réponse différente, même lorsque votre ensemble de données est relativement petit:
Une autre chose que la notation Big-O cache est le facteur de multiplication constant. Par exemple, Quick Select a un multiplicateur très raisonnable, ce qui permet de gagner du temps en l'utilisant sur des ensembles de données extrêmement volumineux.
Une autre chose que vous devez garder à l'esprit est la complexité de l'espace. Très souvent, les algorithmes avec la complexité temporelle O(N*Log N)
auraient une complexité spatiale O(Log N)
. Cela peut poser un problème pour des ensembles de données extrêmement volumineux, par exemple lorsqu'une fonction récursive s'exécute sur un système avec une capacité de pile limitée.
Ça dépend.
Je travaillais chez Amazon, il y avait une méthode qui faisait de la recherche linéaire sur une liste. Nous pourrions utiliser une table de hachage et faire la recherche dans O(1) par rapport à O (n).
J'ai suggéré le changement et il n'a pas été approuvé. parce que l'entrée était petite, cela ne ferait pas une énorme différence.
Cependant, si l'entrée est importante, cela ferait une différence.
Dans une autre société, où les données/entrées étaient énormes, utiliser un arbre, par rapport à List, a fait une énorme différence. Cela dépend donc des données et de l'architecture de l'application.
Il est toujours bon de connaître vos options et comment vous pouvez les optimiser.
Il y a des moments où vous travaillerez avec des milliards d'éléments (et plus), où la différence sera certainement importante.
Il y a d'autres moments où vous travaillerez avec moins d'un millier d'éléments, auquel cas la différence ne sera probablement pas si significative.
Si vous avez une bonne idée de ce à quoi ressembleront vos données, vous devriez avoir une bonne idée de celle à choisir dès le départ, mais la différence entre O(n) et O (n log n ) est suffisamment petit pour qu'il soit probablement préférable de commencer par celui qui est le plus simple, comparez-le et essayez de l'améliorer uniquement si vous constatez qu'il est trop lent.
Cependant, notez que O(n) peut en réalité être plus lent que O (n log n) pour toute valeur donnée de n (en particulier, mais pas nécessairement, pour les petites valeurs de n) en raison de la facteurs constants impliqués, puisque big-O les ignore (il ne prend en compte que ce qui se passe lorsque n tend vers l'infini), donc, si vous regardez uniquement à la complexité temporelle, ce que vous pensez être une amélioration peut en réalité ralentir les choses.
Dark Vador est correct. Cela dépend toujours. Il est également important de rappeler que les complexités sont asymptotiques, dans le pire des cas (généralement) et que les constantes sont abandonnées. Chacun de ceux-ci est important à considérer.
Donc, vous pouvez avoir deux algorithmes, l’un est O(n)) et l’autre est O (nlogn), et pour chaque valeur jusqu’au nombre d’atomes dans l’univers et au-delà ( à une valeur finie de n, l’algorithme O(nlogn) surpasse celui de O(n)). Cela pourrait être dû au fait que les termes d'ordre inférieur sont dominants, ou cela pourrait être dû au fait que dans la moyenne, l'algorithme O(nlogn) est en fait O (n), ou que le nombre réel d'étapes est quelque chose comme 5000 000n vs 3nlogn.
PriorityQueue Trie chaque élément que vous ajoutez à chaque fois lorsque vous utilisez Collections.sort () pour trier tous les éléments en une seule fois. Mais si vous souhaitez obtenir le plus gros élément le plus rapidement possible, utilisez PriorityQueue, en revanche, si vous devez effectuer des calculs mais que l'élément doit être trié, utilisez ArrayList avec Collections.Sort est préférable.