La Arrays.sort
méthode de Java 6 utilise Quicksort pour les tableaux de primitives et le tri par fusion pour les tableaux d'objets. Je pense que la plupart du temps, Quicksort est plus rapide que le tri par fusion et coûte moins de mémoire. Mes expériences soutiennent cela, bien que les deux algorithmes soient O (n log (n)). Alors, pourquoi différents algorithmes sont-ils utilisés pour différents types?
121
Integer
s ou quelque chose?Réponses:
La raison la plus probable: le tri rapide n'est pas stable , c'est-à-dire que les entrées égales peuvent changer leur position relative pendant le tri; entre autres, cela signifie que si vous triez un tableau déjà trié, il risque de ne pas rester inchangé.
Puisque les types primitifs n'ont pas d'identité (il n'y a aucun moyen de distinguer deux entiers avec la même valeur), cela n'a pas d'importance pour eux. Mais pour les types de référence, cela pourrait poser des problèmes pour certaines applications. Par conséquent, un tri de fusion stable est utilisé pour ceux-ci.
OTOH, une raison de ne pas utiliser le tri de fusion stable (garanti n * log (n)) pour les types primitifs peut être qu'il nécessite de faire un clone du tableau. Pour les types de référence, où les objets référencés occupent généralement beaucoup plus de mémoire que le tableau de références, cela n'a généralement pas d'importance. Mais pour les types primitifs, le clonage du tableau double carrément l'utilisation de la mémoire.
la source
Selon la documentation de l'API Java 7 citée dans cette réponse ,
Arrays#Sort()
pour les tableaux d'objets utilise désormais TimSort , qui est un hybride de MergeSort et InsertionSort. En revanche,Arrays#sort()
pour les tableaux primitifs, utilise désormais Dual-Pivot QuickSort . Ces modifications ont été implémentées à partir de Java SE 7.la source
Une raison à laquelle je peux penser est que le tri rapide a une complexité temporelle dans le pire des cas de O ( n ^ 2 ) tandis que le tri-fusion conserve le temps du pire des cas de O ( n log n ). Pour les tableaux d'objets, on s'attend à ce qu'il y ait plusieurs références d'objet en double, ce qui est un cas où le tri rapide est le pire.
Il existe une comparaison visuelle décente de divers algorithmes , accordez une attention particulière au graphique le plus à droite pour différents algorithmes.
la source
Je suivais un cours Coursera sur les algorithmes et dans l'une des conférences, le professeur Bob Sedgewick mentionnait l'évaluation du tri système Java:
la source
java.util.Arrays utilise Quicksort pour les types primitifs tels que int et mergesort pour les objets qui implémentent Comparable ou utilisent un Comparator . L'idée d'utiliser deux méthodes différentes est que si un programmeur utilise des objets, peut-être que l'espace n'est pas une considération cruciale et donc l'espace supplémentaire utilisé par mergesort n'est peut-être pas un problème et si le programmeur utilise des types primitifs, peut-être que la performance est la chose la plus importante, alors utilisez le tri rapide .
Par exemple: voici l'exemple lorsque le tri est important.
C'est pourquoi les tris stables ont un sens pour les types d'objet, en particulier les types d'objet mutables et les types d'objet avec plus de données que la clé de tri, et le tri par fusion est un tel tri. Mais pour les types primitifs, la stabilité n'est pas seulement sans importance. Cela n'a aucun sens.
Source: INFO
la source
La
Arrays.sort
méthode Java utilise le tri rapide, le tri par insertion et le tri par fusion. Il existe même un tri rapide à pivot simple et double implémenté dans le code OpenJDK. L'algorithme de tri le plus rapide dépend des circonstances et les gagnants sont: le tri par insertion pour les petits tableaux (47 actuellement choisis), le tri par fusion pour les tableaux principalement triés, et le tri rapide pour les tableaux restants afin que Array.sort () de Java essaie de choisir le meilleur algorithme pour appliquer en fonction de ces critères.la source