7/23/2019 Algoritmos de Ordenação Em Java http://slidepdf.com/reader/full/algoritmos-de-ordenacao-em-java 1/13 oritmos de Ordenação em Java ://www.devmedia.com.br/algoritmos-de-ordenacao-em-java/32693[30/06/2015 11:33:59] Gostei (3) (0) comentários favorito (3) marcar como lido para impressão anotar Algoritmos de Ordenação em Java Veja neste artigo como funcionam os algoritmos de ordenação InsertionSort, SelectionSort e QuickSort. Neste artigo veremos como aplicar algoritmos de ordenação em Java, dada a sua devida necessidade em ocasiões específicas. Existem diversas aplicabilidades para a ordernação de dados, não só em Java, mas no mundo computacional como um todo. A ideia de conhecer diversos algoritmos para ordenar dados é saber qual utilizar para conseguir um melhor desempenho ou uma melhor legibilidade de código, dependendo da necessidade. Não precisamos usar, por exemplo, um algoritmo “supercomplexo“ para ordenar 10 valores em um vetor, certo? Seria desperdício de tempo desenvolver um algoritmo tão complexo para resolver um problema tão simples. Para analisar um algoritmo de ordenação você deve conhecer a sua complexidade no Pior Caso, Caso Médio e o melhor caso. Estas três características presentes em todos os algoritmos dizem respeito a sua velocidade dada uma situação específica. Atente-se a esses conceitos, pois falaremos deles posteriormente, citando a complexidade do algoritmo através de notação matemática. 0 9 INICIAR ASSINE MVP Buscar
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Sua teoria baseia-se em ordenar os valores da esquerda para a direita, deixando os elementos lidos (a esquerda)
ordenados. Este é geralmente utilizado para ordenar um pequeno número de valores, onde faz-se muito eficiente. A
complexidade do código é:
Complexidade Pior Caso: O(n²)
Complexidade Caso Médio: O(n²)
Complexidade Melhor Caso: O(n)
Quando temos um caso onde a complexidade é n² devemos evitar, visto que a redução de desempenho deste algoritmo é
exponencial. Porém, no seu melhor caso temos uma constante n que significa a inalteração da velocidade, proporcional à
quantidade de elementos.
Lembre-se que estamos trabalhando com proporcionalidade, então dizer que não varia não significa que um vetor de 10
elementos será ordenado na mesma velocidade de um vetor de um milhão de elementos, mesmo no melhor caso, porém a
proporcionalidade entre a quantidade de elementos e sua velocidade continua constante, diferente do Pior Caso que
aumenta ao quadrado.
O melhor caso ocorre quando todos os elementos já estão ordenados e o pior caso é exatamente o contrário, quando todos os elementos estão desordenados. Vejamos um exemplo para entender melhor essa teoria na Listagem 1.
Listagem 1. Aplicando InsertionSort
publ i c stat i c voi d mai n( St r i ng[ ] ar gs) t hr ows I OExcept i on {
i nt quanti dade = 10000;
i nt [ ] vet or = new i nt [ quant i dade] ;
f or ( i nt i = 0; i < vetor . l ength; i ++) { vet or [ i ] = ( i nt ) ( Mat h. r andom( ) *quant i dade) ;
}
l ong t empoI ni ci al = System. cur rent Ti meMi l l i s( ) ;
i nsert i onSort ( vet or) ;
l ong t empoFi nal = Syst em. cur r ent Ti meMi l l i s( ) ;
System. out . pr i nt l n( "Execut ado em = " + ( t empoFi nal - t empoI ni ci al ) + " ms") ;
}
publ i c stat i c voi d i nsert i onSort ( i nt [] vetor) {
f or ( i = j - 1; ( i >= 0) && (vetor [ i ] > key) ; i - - )
{
vetor [ i + 1] = vetor [ i ] ;
} vetor [ i + 1] = key;
}
}
O primeiro passo é entender o funcionamento do método insertionSort(). Este irá percorrer todo o vetor começando do
segundo elemento e atribuindo o mesmo a uma variável chamada key.
O algoritmo começa fazendo uma iteração em todos os elementos do vetor, a partir do segundo elemento, por isso “j=1” e
não “j=0”.
A variável “key” armazena inicialmente o primeiro valor lido pelo laço for, que no caso será o segundo elemento do vetor. O
segundo laço itera sobre os valores que estão antes da variável “key”:
key = vetor[ j ] ;
f or ( i = j - 1; ( i >= 0) && (vetor [ i ] > key) ; i - - )
Perceba que a iteração mostrada continuará até que o valor de i seja maior ou igual a zero e o valor do vetor na posição i
seja maior que o valor de key.
Suponha o seguinte vetor: 30,20,10,40. Na primeira iteração o valor de key será 20, já que começamos a iteração a partir do
segundo valor. Na primeira iteração do segundo laço for o valor de i será igual a 0, porque o j será igual a 1, sendo assim o
i é >= 0 e o vetor[0] é maior que 20, pois vetor[0] = 30. Ao acessar o segundo laço for é feita uma atribuição.
Temos então que vetor[0+1] = vetor[0], ou seja, o valor 20 recebe o valor 30, ficando assim: 30,30,10,40. Quando ele tentar passar pela segunda vez no segundo laço for não será possível, pois i será -1.
Ao sair do segundo laço for o valor de vetor[i+1] recebe o que tínhamos armazenado em key.
No caso, vetor[-1 + 1] = 20, então temos 20, 30, 10, 40.
O mesmo prossegue até que todos os valores do vetor sejam percorridos e estejam ordenados.
A variável “i” serve para comparar sempre o elemento atual com o elemento anterior, pois ele faz com que seja possível
percorrer todos os elementos anteriores ao atual até achar algum que seja maior que o atual, fazendo com que este seja
substituído. Conforme a iteração for avançando os elementos a esquerda vão ficando ordenados.
Tabela 3. Medição do Tempo de execução para QuickSort
Veja que o tempo de processamento do QuickSort é muito bom quando tratamos do caso médio, que é exatamente o nosso
caso (randômico). Veja que o tempo para 200.000 registros é muito eficiente, muito mais que os mostrados anteriormente
para este tipo de caso.
Com isso, vimos que em se tratando de simplicidade, o BubbleSort é o melhor, visto que sua implementação e lógica são
simples e eficazes para uma pequena quantidade de valores, porém precisamos de algoritmos mais robustos quando
sabemos que a entrada se dará para uma grande quantidade de valores.
Por outro lado, o InsertionSort não é tão complexo quanto o QuickSort, mas também não é tão simples quanto o BubbleSort,
acrescentando um pouco mais de robustez e consequentemente desempenho na ordenação de valores. O InsertionSort é
um meio termo e possibilita a ordenação de valores um pouco maiores que o BubbleSort, mas também não consegue
ordenar uma grande quantidade de valores igual ao QuickSort, que por sua vez, mostrou-se o algoritmo mais rápido de
todos e consequentemente o mais complexo de ser implementado. Isso ocorre principalmente pelo fato de ele trabalhar
com recursos como recursividade para alcançar um desempenho notável.
É perceptível que o QuickSort, BubbleSort e InsertionSort possuem quase o mesmo tempo de resposta quando estamos
tratando com até 1000 elementos no vetor, a variação é tão insignificante que a escolha de um destes algoritmos é mais uma questão pessoal do que profissional.
Ao trabalhar com uma quantidade de valores maior, já percebemos que algoritmos simples podem não ser a melhor
escolha, você mesmo pode fazer um teste tentando executar o BubbleSort para um milhão de elementos. Se para 200.000
elementos o tempo de resposta foi quase 82 segundos e o mesmo cresce de forma exponencial, então para um milhão de
elementos possivelmente chegará perto ou passará (dependendo do hardware) de horas.
Testamos de forma exaustiva o algoritmo QuickSort para o melhor caso com 100 elementos no vetor, e constatamos que em alguns momentos ocorrem alguns picos de velocidade onde o retorno muda de 1ms para 5ms, apontando uma pequena
perda de desempenho. Testando a mesma quantidade de elementos para o melhor caso no BubbleSort a variável não
ocorreu nenhuma vez, mantendo a velocidade sempre em 1ms. Apontando um ponto positivo para o algoritmo mais simples
em casos específicos.
Ronaldo Lanhellas
Bacharel em Ciência da Computação (UNAMA). Cursando Pós-Graduação em Tecnologias WEB (UFPA). Trabalhando atualmente como Analista de