O Arrays.sort
método do Java 6 usa Quicksort para arrays de primitivos e merge sort para arrays de objetos. Eu acredito que na maioria das vezes o Quicksort é mais rápido do que merge sort e custa menos memória. Meus experimentos confirmam isso, embora ambos os algoritmos sejam O (n log (n)). Então, por que algoritmos diferentes são usados para tipos diferentes?
121
Integer
s ou algo assim?Respostas:
O motivo mais provável: o quicksort não é estável , ou seja, entradas iguais podem mudar sua posição relativa durante a classificação; entre outras coisas, isso significa que se você classificar uma matriz já classificada, ela pode não permanecer inalterada.
Como os tipos primitivos não têm identidade (não há como distinguir dois ints com o mesmo valor), isso não importa para eles. Mas, para tipos de referência, isso pode causar problemas para alguns aplicativos. Portanto, uma classificação de mesclagem estável é usada para eles.
OTOH, uma razão para não usar a classificação de mesclagem estável (garantida n * log (n)) para tipos primitivos pode ser que ela requer a criação de um clone da matriz. Para os tipos de referência, onde os objetos referidos geralmente ocupam muito mais memória do que o array de referências, isso geralmente não importa. Mas para tipos primitivos, clonar o array dobra o uso de memória.
fonte
De acordo com os documentos da API Java 7 citados nesta resposta ,
Arrays#Sort()
para matrizes de objetos agora usa TimSort , que é um híbrido de MergeSort e InsertionSort. Por outro lado,Arrays#sort()
para matrizes primitivas agora usa Dual-Pivot QuickSort . Essas mudanças foram implementadas a partir do Java SE 7.fonte
Uma razão que posso pensar é que quicksort tem um pior caso de complexidade de tempo de O ( n ^ 2 ), enquanto mergesort retém o pior caso de tempo de O ( n log n ). Para matrizes de objetos, há uma expectativa razoável de que haverá várias referências de objeto duplicadas, o que é um caso em que o quicksort tem pior desempenho.
Há uma comparação visual decente de vários algoritmos , preste atenção especial ao gráfico mais à direita para diferentes algoritmos.
fonte
Eu estava fazendo a aula do Coursera sobre Algoritmos e em uma das palestras o Professor Bob Sedgewick mencionou a avaliação para o sistema Java sort:
fonte
java.util.Arrays usa quicksort para tipos primitivos como int e mergesort para objetos que implementam Comparable ou usam um Comparator . A ideia de usar dois métodos diferentes é que se um programador está usando objetos talvez o espaço não seja uma consideração criticamente importante e então o espaço extra usado por mergesort talvez não seja um problema e se o programador está usando tipos primitivos talvez o desempenho seja a coisa mais importante, então use o quicksort .
Por exemplo: Este é o exemplo ao classificar questões de estabilidade.
É por isso que classificações estáveis fazem sentido para tipos de objetos, especialmente tipos de objetos mutáveis e tipos de objetos com mais dados do que apenas a chave de classificação, e mergesort é esse tipo de classificação. Mas, para os tipos primitivos, a estabilidade não é apenas irrelevante. Não tem sentido.
Fonte: INFO
fonte
O
Arrays.sort
método Java usa quicksort, inserção por inserção e mergesort. Há até mesmo um quicksort de pivô único e duplo implementado no código OpenJDK. O algoritmo de classificação mais rápido depende das circunstâncias e os vencedores são: classificação por inserção para pequenos arrays (47 atualmente escolhidos), mergesort para arrays principalmente classificados e quicksort para os arrays restantes, então Array.sort () do Java tenta escolher o melhor algoritmo para aplicar com base nesses critérios.fonte