Você está na página 1de 24

performance de algoritmos de ordenação de dados

Santana de Parnaíba – SP

2017
ATIVIDADES PRÁTICAS SUPERVISIONADAS (APS):
Desenvolvimento de sistema para análise de performance de algoritmos de
ordenação de dados

Trabalho de Atividade Prática Supervisiona apresentado


à Universidade Paulista – UNIP como exigência parcial
para obtenção do titulo em bacharel em ciências
da computação. Orientador: Elias Oliveira.

Santana de Parnaíba – SP
2017
ATIVIDADES PRÁTICAS SUPERVISIONADAS (APS):
Desenvolvimento de sistema para análise de performance de algoritmos de
ordenação de dados

Trabalho de Atividade Prática Supervisionada apresentada


à Universidade Paulista – UNIP como exigência parcial
para obtenção do titulo em bacharel em ciências da
computação.Orientador: Elias Oliveira.

Aprovado em __/__/__

BANCA EXAMINADORA

SUMÁRIO

1 INTRODUÇÃO...........................................................................................................................5
2 ALGORITMO DE ORDENAÇÃO POR TROCA....................................................................6

2.1 BubbleSort..............................................................................................................................6

2.2 QuickSort................................................................................................................................8

3 ALGORITMO DE ORDENAÇÃO POR INSERÇÃO...........................................................11

3.1 InsertionSort.........................................................................................................................11

4 ALGORITMO DE ORDENAÇÃO POR SELEÇÃO ............................................................13

4.1 SelectionSort .......................................................................................................................13

5 DESEMPENHO DOS ALGORITMOS DE ORDENAÇÃO.................................................15

6 Conclusão.................................................................................................................................21

7 BIBLIOGRAFIA........................................................................................................................22

INDICE DE ILUSTRAÇÕES TABELAS E FIGURAS

Tabela 1. Medição de Tempo para BubbleSort............................................................................9

Tabela 2. Medição de Tempo para QuickSort.............................................................................11


Tabela 3.Medição de Tempo para InsertionSort.......................................................................15

Figura 1.Esquema de Funcionamento do BubbleSort..........................................8

Figura 2.Esquema de Funcionamento do QuickSort.................................................................10

Figura 3.Esquema de Funcionamento do InsertionSort............................................................13

Figura 4.Medição de Tempo para InsertionSort.........................................................................14

Figura 5.Esquema de Funcionamento do SelectionSort...........................................................15

1 INTRODUÇÃO
Este trabalho tem como objetivo visar entre as diversas estruturas de dados,
vamos discutir seu armazenamento, algoritmos e métodos de aplicabilidade
Considerada uma estrutura de dados não primitiva, a lista linear permite
representar um conjunto de dados que se relacionam entre si. Construindo
informações, das quais podemos buscar, incluir, remover, alterar e ate
combinar duas ou mais listas de um determinado elemento.
Consideradas como básicas, é preciso saber qual utilizar para obter um
desempenho melhor ou conseguir ler com maior facilidade seu código, o qual
facilitará o desempenho de acordo com sua necessidade.
Desta forma, precisamos entender a necessidade do algoritmo para determinar
a ordenação a ser utilizada para o pior caso, médio caso e o melhor caso.
Dentre as características anteriormente mencionadas, determinaremos a
velocidade para sanar nossa necessidade em determinada situação.
Desta maneira, vejamos os principais métodos para ordenarmos os dados:
 Ordenação por troca
 BubbleSort (método bolha)
 QuickSort (método de troca e repetição)
 Ordenação por inserção
 InsertionSort (método de inserção direta)
 ShellSort (método otimizado de inserção)
 Ordenação por seleção
 SelectionSort (método da seleção direta)
 HeapSort (método da seleção em árvore)

2 ALGORITMO DE ORDENAÇÃO POR TROCA


Dispomos de dois exemplos para ordenação por troca, sendo o BubbleSort,
com sua simplicidade percorre a lista em seqüência por varias vezes,
comparando cada elemento ate que seus valores estejam em ordem correta.
Já o QuickSort é a ordenação por troca mais utilizado, visto sua troca de
partição, onde posiciona o vetor em duas partes e assim as ordena
separadamente.

2.1 BubbleSort
O BubbleSort (também conhecido como método bolha) é simples e eficaz ao
ordenar pequenos números onde compara todos os valores, através de varias
trocas entre pares adjacentes de elementos, sempre que o próximo elemento
for menor que o anterior. Após a varredura no vetor e desde que o maior e
menor número esteja corretamente posicionado (dependendo de que forma
será solicitada a ordenação) ele não será mais comparado.
Abaixo veremos como é realizada a troca:

Figura 1. Esquema de Funcionamento do BubbleSort

Vejamos sua implementação:

public static void main(String[] args) throws IOException {


int quantidade = 10000;
int[] vetor = new int[quantidade];
for (int i = 0; i < vetor.length; i++) {
vetor[i] = (int) (Math.random()*quantidade);
}
long tempoInicial = System.currentTimeMillis();
bubbleSort(vetor);
long tempoFinal = System.currentTimeMillis();
System.out.println("Executado em = " + (tempoFinal -
tempoInicial) + " ms");
}
private static void bubbleSort(int vetor[]){
boolean troca = true;
int aux;
while (troca) {
troca = false;
for (int i = 0; i < vetor.length - 1; i++) {
if (vetor[i] > vetor[i + 1]) {
aux = vetor[i];
vetor[i] = vetor[i + 1];
vetor[i + 1] = aux;
troca = true;
}
}
}
}

No laço while() foi criado e executado enquanto o valor de troca for true, sendo
que na primeira interação foi configurada como false.
O laço for percorre o primeiro elemento ate que o ultimo elemento -1 (nuca
chega a ler o ultimo elemento) verificando se o elemento atual é maior que o
próximo elemento que será lido.
Para verificarmos se a variável troca é útil, quando passa pela primeira vez no
vetor de elementos sendo realizada qualquer troca efetiva será true, fazendo
com que faça nova varredura em todos os elementos ate que todos estejam
devidamente ordenados.

Abaixo temos exemplificando a medição com x elementos e o tempo gasto


para ordenação:
ELEMENTOS CASO MÉDIO MELHOR CASO
100 0 ms 0 MS
1.000 15 ms 0 ms
10.000 200 ms 0 ms
100.000 20.424 ms 2 ms
200.000 81.659 ms 4 ms

Tabela 1. Medição de Tempo para BubbleSort

Em uma breve analise, percebemos que ate 1.000 elementos o BubbleSort é


eficiente onde realiza a ordenação de forma eficaz, já quando temos mais
elementos ele se torna lento.

2.2 QuickSort

O QuickSort (também conhecido como método de troca e repetição) é mais


eficiente, visto que quando o vetor vai sendo ordenado são realizadas partições
recursivas, onde se ganha tempo no desempenho. Escolhe um elemento
qualquer da lista, onde se denomina pivô, sendo que os elementos que estão
localizados antes do pivô devem ser menores e os que estiverem depois
devem ser maiores que ele. Assim quando esse processo de separação estiver
finalizado, o pivô deverá estar exatamente ao meio da lista.
Desta forma, reduz problemas complexos em problemas mais simples para
melhor solução.
Abaixo veremos como é realizada a troca:
Figura 2.Esquema de Funcionamento do QuickSort

Vejamos sua implementação:


public static void main(String[] args) throws IOException {
int quantidade = 10000;
int[] vetor = new int[quantidade];
for (int i = 0; i < vetor.length; i++) {
vetor[i] = (int) (Math.random()*quantidade);
}
long tempoInicial = System.currentTimeMillis();
quickSort(vetor,0,vetor.length-1);
long tempoFinal = System.currentTimeMillis();
System.out.println("Executado em = " + (tempoFinal -
tempoInicial) + " ms");
}
private static void quickSort(int[] vetor, int inicio, int
fim) {
if (inicio < fim) {
int posicaoPivo = separar(vetor, inicio, fim);
quickSort(vetor, inicio, posicaoPivo - 1);
quickSort(vetor, posicaoPivo + 1, fim);
}
}
private static int separar(int[] vetor, int inicio, int fim)
{
int pivo = vetor[inicio];
int i = inicio + 1, f = fim;
while (i <= f) {
if (vetor[i] <= pivo)
i++;
else if (pivo < vetor[f])
f--;
else {
int troca = vetor[i];
vetor[i] = vetor[f];
vetor[f] = troca;
i++;
f--;
}
}
vetor[inicio] = vetor[f];
vetor[f] = pivo;
return f;
}
A principio separa-se as listas para que seja determinado o pivô, elemento que
será divisível em ambas as listas, onde será feita a separação dentro de uma
sublista, sendo feito desta forma ate que todos os elementos estejam
ordenados.

Abaixo temos exemplificando a medição com x elementos e o tempo gasto para


ordenação:

ELEMENTOS CASO MÉDIO


100 0 ms
1.000 0 ms
10.000 39 ms
100.000 43 ms
200.000 50 ms

Tabela 2. Medição de Tempo para QuickSort


O tempo de processamento de dados com 200.000 registros é bastante
eficiente, bem maior que o caso apresentado no BubbleSort.
De toda forma, por sua vez o QuickSort é mais rápido, porem é mais complexo
em sua implementação, devido ao fato de trabalhar com recursos recursivos.

3 ALGORITMO DE ORDENAÇÃO POR INSERÇÃO


Dispomos de exemplo para ordenação por inserção, o InsertionSort ordena um
conjunto de valores sendo da esquerda para direita.

3.1 InsertionSort
O InsertionSort (também conhecido por método de inserção direta) baseia-se
em ordenar da esquerda para a direita, onde os elementos lidos a esquerda
ficam ordenados, eficiente em ordenar um menor número de valores.
Abaixo veremos como é realizada a troca:

Figura 3.Esquema de Funcionamento do InsertionSort

Aplicando InsertionSort

public static void main(String[] args) throws IOException {


int quantidade = 10000;
int[] vetor = new int[quantidade];
for (int i = 0; i < vetor.length; i++) {
vetor[i] = (int) (Math.random()*quantidade);
}
long tempoInicial = System.currentTimeMillis();
insertionSort(vetor);
long tempoFinal = System.currentTimeMillis();
System.out.println("Executado em = " + (tempoFinal -
tempoInicial) + " ms");
}
public static void insertionSort(int[] vetor) {
int j;
int key;
int i;
for (j = 1; j < vetor.length; j++)
{
key = vetor[j];
for (i = j - 1; (i >= 0) && (vetor[i] > key); i--)
{
vetor[i + 1] = vetor[i];
}
vetor[i + 1] = key; }
}
Neste caso o vetor será percorrido começando do segundo elemento o qual
será atribuído a variável key.

Abaixo temos exemplificando a medição com x elementos e o tempo gasto para ordenação:

ELEMENTOS CASO MÉDIO MELHOR CASO


100 0 ms 0 ms
1.000 11 ms 0 ms
10.000 220 ms 1 ms
100.000 5110 ms 6 ms
200.000 20.272 ms 8 ms

Figura 4.Medição de Tempo para InsertionSort


Percebemos neste caso que no médio tempo temos uma boa interação, tendo
um aumento de tempo proporcional ao aumento de elementos.

4 ALGORITMO DE ORDENAÇÃO POR SELEÇÃO


Dispomos do exemplo de ordenação por seleção, o SelectionSort o qual
seleciona vários elementos e os dispõe em suas posições corretas na ordem
solicitada.

4.1 SelectionSort
O SelectionSort (também conhecido como método de seleção direta) o vetor
selecionará sequencialmente os vetores de ordenação localizando o próximo
que seja o menor ou maior valor, sendo comparado ao do inicio, se verdadeira
a posição é trocada, assim ordenara o algoritmo.

Figura 5.Esquema de Funcionamento do SelectionSort

Aplicação do SelectionSort
// Função select_sorte – Recebe uma matriz desordenada e a ordena com 
// algoritmo select sort 
// 
// Entradas – matriz a ser ordenada 
//                 - tamanho da matriz a ordenar 
// Saídas - nenhuma 
void select_sort(unsigned char matriz[], unsigned int tamanho){ 

   unsigned char temp; 


    unsigned int atual, j; 
   for (atual=0; atual < tamanho; atual++) 
        for (j = atual + 1; j < tamanho; j++) 
             if (matriz[atual] > matriz[j]){ 
                  temp=matriz[atual]; 
                  matriz[atual]=matriz[j]; 
                  matriz[j]=temp; 
             } 
}

Abaixo temos exemplificando a medição com x elementos e o tempo gasto para


ordenação:

ELEMENTOS CASO MÉDIO MELHOR CASO

100 38 ms 0 ms
1.000 359 ms 0 ms

10.000 3558 ms 0 ms

Tabela 3.Medição de Tempo para InsertionSort


5 DESEMPENHO DOS ALGORITMOS DE ORDENAÇÃO
Para analise de desempenho utilizamos os seguintes algoritmos de ordenação:
 BubbleSort
 QuickSort
 InsertionSort

Desta forma seguem os teste de acordo com os métodos utilizados:


 BubbleSort

import java.io.IOException;

public class BubbleSort {


/**
* @param args the command line arguments
* @throws java.io.IOException
*/
public static void main(String[] args) throws IOException {

int quantidade = 10000;

int[] vetor = new int[quantidade];

for (int i = 0; i < vetor.length; i++) {


vetor[i] = (int) (Math.random()*quantidade);

long tempoInicial = System.currentTimeMillis();

bubbleSort(vetor);

long tempoFinal = System.currentTimeMillis();


System.out.println("Com o valor de :" +quantidade+" a ordenação de
BubbleSort leva o tempo de ");
System.out.println("Execução em = " + (tempoFinal - tempoInicial) + "
ms");
}

private static void bubbleSort(int vetor[]){


boolean troca = true;
int aux;
while (troca) {
troca = false;
for (int i = 0; i < vetor.length - 1; i++) {
if (vetor[i] > vetor[i + 1]) {
aux = vetor[i];
vetor[i] = vetor[i + 1];
vetor[i + 1] = aux;
troca = true;
}
}
}
}

Analisando seu desempenho com diversos valores, o BubbleSort apresentou-


se como pior método de ordenação.
 QuickSort

package quicksort;

import java.io.IOException;

public class QuickSort {

/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException {

int quantidade = 100000;


int[] vetor = new int[quantidade];

for (int i = 0; i < vetor.length; i++) {


vetor[i] = (int) (Math.random()*quantidade);

long tempoInicial = System.currentTimeMillis();

quickSort(vetor,0,vetor.length-1);

long tempoFinal = System.currentTimeMillis();

System.out.println("Com o valor de :" +quantidade+" a ordenação de


QuickSort leva o tempo de " );
System.out.println("Execução em = " + (tempoFinal - tempoInicial) + "
ms");
}

private static void quickSort(int[] vetor, int inicio, int fim) {


if (inicio < fim) {
int posicaoPivo = separar(vetor, inicio, fim);
quickSort(vetor, inicio, posicaoPivo - 1);
quickSort(vetor, posicaoPivo + 1, fim);
}
}
private static int separar(int[] vetor, int inicio, int fim) {
int pivo = vetor[inicio];
int i = inicio + 1, f = fim;
while (i <= f) {
if (vetor[i] <= pivo)
i++;
else if (pivo < vetor[f])
f--;
else {
int troca = vetor[i];
vetor[i] = vetor[f];
vetor[f] = troca;
i++;
f--;
}
}

vetor[inicio] = vetor[f];
vetor[f] = pivo;
return f;
}

}
//Esse algoritmo é Executado em = 31 ms
Analisando seu desempenho com diversos valores, o QuickSort obteve o
melhor resultado na maioria dos testes. Sua eficiência foi identificada apenas
nos grandes arquivos.

 InsertionSort

package insertionsort;

import java.io.IOException;

public class InsertionSort {

/**
* @param args the command line arguments
* @throws java.io.IOException
*/
public static void main(String[] args) throws IOException {

int quantidade = 100000;


int[] vetor = new int[quantidade];
System.out.println("Com o valor de :"+quantidade+" a ordenação de
InsertionSort leva o tempo de ");
for (int i = 0; i < vetor.length; i++) {
vetor[i] = (int) (Math.random()*quantidade);
}

long tempoInicial = System.currentTimeMillis();

insertionSort(vetor);

long tempoFinal = System.currentTimeMillis();

System.out.println("Execução em = " + (tempoFinal - tempoInicial) + "


ms");
}

public static void insertionSort(int[] vetor) {


int j;
int key;
int i;

for (j = 1; j < vetor.length; j++)


{
key = vetor[j];
for (i = j - 1; (i >= 0) && (vetor[i] > key); i--)
{
vetor[i + 1] = vetor[i];
}
vetor[i + 1] = key;
}
}
}

Analisando seu desempenho com diversos valores, o InsertionSort em arranjos


já ordenados demonstra um comportamento linear, sendo útil para ordenação
de arquivo com poucos elementos fora da ordem.

 
6 Conclusão
Como era esperado, os algoritmos BubbleSort e InsertionSort tiveram
desempenhos muito inferiores aos QuickSort. Fica muito visível quando se
processa a organiza ção com um milhão de entradas, onde os dois primeiros
demoram mais de duas horas para processar enquanto os outros demoram
menos de um segundo. Também é visível a complexidade dos algoritmos se
pararmos para analisar as comparações e trocas. Nos primeiros algoritmos, a
taxa de aumento de trocas e comparações é superior a que a taxa dos últimos
dois algoritmos. O QuickSort possui um desempenho melhor com um milhão de
entradas do que os dos primeiros algoritmos usando dez mil elementos.
Entretanto, não podemos esquecer que cada algoritmo possui sua utilidade.
Por exemplo, em alguma aplicação onde o volume de dados é pequena e há
pouca inserção de novos dados, o InsertionSort pode sim ser utilizado, pois
bases de dados que estejam quase organizadas têm um desempenho razoável
com esse algoritmo.
7 BIBLIOGRAFIA

(16/01/2017) Famílias de métodos de ordenação de dados: análise do desempenho. 


Ordenação interna: bolha, ordenação por seleção, ordenação por inserção, shellsort. 
Bibliografia: cap. 4 do livro do Ziviani (2011). pp. 101-109. 

(16/01/2017) Ordenação interna: heapsort. Método da partição e troca (quicksort).


Comparação entre os métodos de ordenação interna. 
Bibliografia: cap. 4 do livro do Ziviani (2011). pp.109-124

Você também pode gostar