web-dev-qa-db-fra.com

Pourquoi la méthode Arrays.sort de Java utilise-t-elle deux algorithmes de tri différents pour des types différents?

La méthode Arrays.sort 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 supportent cela, bien que les deux algorithmes soient O (n log (n)). Alors, pourquoi différents algorithmes sont-ils utilisés pour différents types?

97
zjffdu

La raison la plus probable: quicksort n’est pas stable , c’est-à-dire que des entrées identiques peuvent modifier leur position relative pendant le tri; cela signifie notamment que si vous triez un tableau déjà trié, il ne restera peut-être pas inchangé.

Comme les types primitifs n’ont pas d’identité (il n’ya aucun moyen de distinguer deux entiers de même valeur), cela n’a aucune 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 pour ne pas utiliser le type de fusion stable (n * log (n)) stable pour les types primitifs peut être que cela nécessite la création d'un clone du tableau. Pour les types de référence, où les objets référencés utilisent 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 pur de la matrice double l'utilisation de la mémoire.

166
Michael Borgwardt

Selon les documents de l'API Java 7 cités dans this answer , Arrays#Sort() pour les tableaux d'objets utilise maintenant TimSort , un hybride de MergeSort et InsertionSort. Par contre, Arrays#sort() pour les tableaux primitifs utilise maintenant Dual-Pivot QuickSort . Ces modifications ont été implémentées à partir de Java SE 7.

20
Will Byrne

Une raison pour laquelle je peux penser est que quicksort a une complexité temporelle dans le cas le plus défavorable égale à O ( n ^ 2 ), tandis que mergesort conserve le pire cas dans lequel elle est stockée ( n log n ). Pour les tableaux d'objets, on peut raisonnablement s'attendre à ce qu'il y ait plusieurs références d'objet en double, ce qui est le cas dans lequel le tri rapide est pire.

Il y a une bonne comparaison visuelle de divers algorithmes , faites particulièrement attention au graphe le plus à droite pour différents algorithmes.

12
msw

Je suivais le cours d'algorithmes de Coursera et, dans l'une des conférences, le professeur Bob Sedgewick mentionnait l'évaluation du type de système Java:

"Si un programmeur utilise des objets, l’espace n’est peut-être pas une considération cruciale. L’espace supplémentaire utilisé par un type de fusion peut ne pas être un problème. Et si un programmeur utilise des types primitifs, peut-être. la performance est la chose la plus importante alors ils utilisent le tri rapide. "

4
kukido

La méthode Arrays.sort de Java utilise quicksort, tri par insertion et mergesort. Il existe même un quicksort simple et double pivot implémenté dans le code OpenJDK. L'algorithme de tri le plus rapide dépend des circonstances. Les gagnants sont: le tri par insertion pour les petits tableaux (47 actuellement choisis), mergesort pour les tableaux principalement triés et le tri rapide pour les tableaux restants, de sorte que Array.sort () de Java essaie de choisir le meilleur algorithme appliquer en fonction de ces critères.

0
David McManamon

(Java.util.Arrays) utilise quicksort pour les types primitifs tels que int et mergesort pour les objets qui implémentent Comparable ou utilisent un Comparateur . L'idée d'utiliser deux méthodes différentes est que si un programmeur utilise des objets, l'espace n'est peut-être pas une considération d'une importance cruciale et que l'espace supplémentaire utilisé par mergesort n'est peut-être pas un problème et que si le programmeur utilise des types primitifs, les performances sont la chose la plus importante alors utilisez le quicksort .

Par exemple: Ceci est l'exemple lorsque le tri de la stabilité est important.

 enter image description here 

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 mergesort en est un. Mais pour les types primitifs, la stabilité n’est pas seulement sans importance. Cela n’a aucun sens.

Source: INFO

0
Dinesh Kumar