2. 2
Ordenação é o ato de se
colocar os elementos de uma
sequência de informações, ou
dados, em uma ordem
predefinida.
Algoritmos a serem vistos:
BubbleSort
Seleção
Inserção
MergeSort
QuickSort
Métodos Simples
Métodos Eficientes
Rápidos (menos da metade do tempo
que os métodos simples)
3. 3
Sua ideia é criar uma sequência
ordenada a partir de duas outras
também ordenadas. Para isso, ele divide
a sequência original em pares de dados,
ordena-as; depois as agrupa em
sequências de quatro elementos, e assim
por diante, até ter toda a sequência
dividida em apenas duas partes.
ou ordenação por intercalação
O coração do algoritmo MergeSort é a intercalação de
dois vetores já ordenados.
Intercalar dois vetores ordenados A e B criará um terceiro C,
que contem todos os elementos de A e B, também
organizados de maneira ordenada.
4. Imagine dois vetores ordenados que podem ter
tamanhos diferente. O vetor A com 4 elementos e
o vetor B com 6.
Eles serão intercalados em um vetor C que a
principio começa com 10 células vazias.
23 47 81 95A
0 1 2 3
Intercalação
7 14 39 55 62 74B
0 1 2 3 4 5
C
0 1 2 3 4 5 6 7 8 9
5. Os dois vetores A e B serão intercalados no vetor C
que se inicia vazio:
23 47 81 95A
0 1 2 3
7 14 39 55 62 74B
0 1 2 3 4 5
C
0 1 2 3 4 5 6 7 8 9
7 14 23 39 47 55 62 74 81 95C
0 1 2 3 4 5 6 7 8 9
Antesda
intercalação
Depois da
intercalação
6. Os dois vetores A e B serão intercalados no vetor C
que se inicia vazio:
23 47 81 95A
0 1 2 3
7 14 39 55 62 74B
0 1 2 3 4 5
C
0 1 2 3 4 5 6 7 8 9
7 14 23 39 47 55 62 74 81 95C
0 1 2 3 4 5 6 7 8 9
Depois da
intercalação
Passo Compara Cópia
para C
1 23 e 7 7 de B
2 23 e 14 14 de B
3 23 e 39 23 de A
4 39 e 47 39 de B
5 55 e 47 47 de A
6 55 e 81 55 de B
7 62 e 81 62 de B
8 74 e 81 74 de B
9 Não há 81 de A
10 Não há 95 de A
Intercalação
1 2
3
4
5
6 7 8
9
10
7. class Intercala {
public static void main (String[] args) {
int[] vA = {2, 47, 81, 95};
int[] vB = {7, 14, 39, 55, 62, 74};
int[] vC = new int[10];
inter(vA, 4, vB, 6, vC);
imprime(vC, 10);
} // fim programa principal
public static void imprime(int[] v, int n) {
for (int i=0; i<n; i++)
System.out.print(v[i] + " ");
System.out.println("");
} // fim função imprime
Intercalação de dois vetores
Continua ...
8. public static void inter(int[] vA, int nA, int[] vB, int nB,
int[] vC) {
int i=0, j=0, k=0; // índice para os vetores A, B e C
while (i < nA && j < nB) {
if (vA[i] < vB[j]) { vC[k] = vA[i];
k++; i++; }
else { vC[k] = vB[j];
k++; j++; }
}
while (i < nA) { // se vetor A não esta vazio ainda
vC[k] = vA[i];
k++; i++; }
while (j < nB) { // se vetor B não esta vazio ainda
vC[k] = vB[j];
k++; j++; }
} // fim função inter
} // fim classe Intercala
Esvaziando vetores
A e B inserindo-os
no vetor C
ordenadamente
9. public static void inter(int[] vA, int nA, int[] vB, int nB,
int[] vC) {
int i=0, j=0, k=0; // índice para os vetores A, B e C
while (i < nA && j < nB) {
if (vA[i] < vB[j]) { vC[k] = vA[i];
k++; i++; }
else { vC[k] = vB[j];
k++; j++; }
}
while (i < nA) {
vC[k] = vA[i];
k++; i++; }
while (j < nB) {
vC[k] = vB[j];
k++; j++; }
} // fim função inter
} // fim classe Intercala
Percorre o vetor A e B
comparando os
elementos e copiando o
menor para o vetor C
Situação onde todos os elementos foram
transferidos do vetor B mas, o vetor A ainda
possui elementos. O laço copia os elementos
restantes do vetor A para o C
Lida com situação similar, onde todos os
elementos foram transferidos do vetor A mas, o
vetor B ainda possui elementos. O laço copia os
elementos restantes do vetor B para o vetor C
10. 10
Ordenando por Intercalação
A ideia da ordenação por intercalação é dividir um vetor ao
meio, ordenar cada metade e então usar o método inter() para
intercalar as duas metades em um único vetor ordenado.
7 14 23 39 47 55 62 74 81 95
aux
0 1 2 3 4 5 6 7 8 9
Exemplo:
23 47 81 95 7 14 39 55 62 74v
0 1 2 3 4 5 6 7 8 9
23 47 81 95
A
0 1 2 3
7 14 39 55 62 74
B
0 1 2 3 4 5
1 23 e 7 7 de B
2 23 e 14 14 de B
3 23 e 39 23 de A
4 39 e 47 39 de B
5 55 e 47 47 de A
6 55 e 81 55 de B
7 62 e 81 62 de B
8 74 e 81 74 de B
9 Não há 81 de A
10 Não há 95 de A
Intercalação
Copia
para C
11. class IntercalaJuntos {
public static void main (String[] args) {
int[] v = {2, 47, 81, 95, 7, 14, 39, 55, 62, 74};
int n=10; // numero de itens do vetor v
int inicio=0; // indice inicial do vetor v
int fim=n-1; // indice final do vetor v
int meio=(inicio+fim)/2; // indice do meio do vetor v
inter(v,inicio,meio,fim);
imprime(v,n);
} // fim programa principalb
public static void imprime(int[] v, int n) {
for (int i=0; i<n; i++)
System.out.print(v[i] + " ");
System.out.println("");
} // fim função imprime
Intercalação de um vetor
Continua ...
12. public static void inter(int[] v, int inicio, int meio, int
fim) {
int i=inicio;
int j=meio;
int[] aux = new int[fim+1];
int k=0; // indice para o vetor auxiliar
while (i < meio && j < fim+1) {
if (v[i] < v[j]) aux[k++] = v[i++];
else aux[k++] = v[j++];
}
while (i < meio) aux[k++] = v[i++]; // se parte 1 não vazia
while (j < fim+1) aux[k++] = v[j++];// se parte 2 não vazia
for(i=inicio; i<fim+1; i++) v[i]=aux[i];
} // fim função inter
} // fim classe Intercala
copiando os valores
do vetor ordenado
(aux) no vetor v
inserindo os itens
do vetor v
ordenadamente no
vetor aux
13. 13
O MergeSort é um algoritmo de ordenação por comparação
do tipo dividir-para-conquistar.
Sua ideia básica consiste em Dividir (o problema em vários
sub-problemas e resolver esses sub-problemas através da
recursividade) e Conquistar (após todos os sub-problemas
terem sido resolvidos ocorre a conquista (intercalação) que é
a união das resoluções dos sub-problemas).
14. 14
public static void MergeSort
(int[] v, int inicio, int fim) {
if(inicio == fim) return;
int meio=(inicio+fim)/2;
MergeSort(v,inicio,meio);
MergeSort(v,meio+1,fim);
intercala(v,inicio,meio,fim);
}
função MergeSort:
Os passos para o algoritmo MergeSort são:
Passo 1. Dividir uma sequência em duas novas sequências.
Passo 2. Ordenar, recursivamente, cada uma das sequências
(dividindo novamente, quando possível).
Passo 3. Combinar (merge) as subsequências para obter o resultado
final.
15. 15
class Programa1 {
public static void main (String[] args) {
int[] v = {2, 47, 81, 95, 7, 14, 39, 55, 62, 74};
MergeSort(v,0,9);
imprime(v,10);
}
public static void imprime(int[] v, int n) {
for (int i=0; i<n; i++)
System.out.print(v[i] + " ");
System.out.println("");
}
public static void MergeSort (int[] v, int inicio, int fim)
{
if(inicio==fim) return;
int meio=(inicio+fim)/2;
MergeSort(v,inicio,meio);
MergeSort(v,meio+1,fim);
intercala(v,inicio,meio,fim);
}
Exemplo de uso da função MergeSort
// Continua ...
16. 16
public static void intercala(int[] v, int inicio, int meio,
int fim) {
int[] aux = new int[fim-inicio+1];
int i = inicio;
int j = meio+1;
int k = 0;
while ( i<=meio && j<=fim )
if ( v[i] <= v[j] ) aux[k++] = v[i++];
else aux[k++] = v[j++];
while ( i <= meio ) aux[k++] = v[i++];
while ( j <= fim ) aux[k++] = v[j++];
for ( i=0; i<(fim-inicio+1); i++) v[inicio + i] = aux[i];
}
} // fim classe Programa1
copiando os valores do vetor
ordenado (aux) no vetor v
Inserindo os
itens do vetor v
ordenadamente
no vetor aux
17. 17
Vantagem:
Desvantagem:
Em comparação com os outros algoritmos de ordenação
vistos (inserção, seleção e bubblesort) o MergeSort é mais
rápido e eficiente quando usado para uma grande quantidade
de dados
Gasto extra de memória, o algoritmo
cria uma cópia do vetor para cada nível
da chamada recursiva
18. 18
Também adota a estratégia de divisão
e conquista.
Inicia com a partição do vetor em
dois subvetores, de tal maneira que
todos os elementos do primeiro vetor
sejam menores ou iguais a todos os
elementos do segundo vetor.
Estabelecida a divisão o problema estará resolvido, pois
aplicando recursivamente a mesma técnica a cada um dos
subvetores, o vetor estará ordenado ao se obter um subvetor
de apenas 1 elemento.
19. 19
Passo 1. Seleciona um elemento do
conjunto S. O elemento selecionado (p)
é chamado de pivô.
Os passos para ordenar uma
sequência S = { a1, a2, a3, …, an } é
dado por:
► O processo é finito, pois a cada iteração pelo menos um
elemento é posto em sua posição final e não será mais
manipulado na iteração seguinte.
Passo 2. Retire p de S e particione os elementos restantes de S
em seqüências distintas, L e G.
Passo 3. A partição L deverá ter os elementos menores ou iguais
ao elemento pivô p, enquanto que a partição G conterá os
elementos maiores ou iguais a p.
Passo 4. Aplique novamente o algoritmo nas partições L e G.
20. 20
public static void QuickSort (int[] v, int esq, int dir) {
int i = esq;
int j = dir;
int pivo = v [ (esq+dir)/2 ];
int aux;
do {
while (v[i]<pivo && i<dir)
i++;
while (pivo<v[j] && j>esq)
j--;
if (i<=j) {
aux = v[i];
v[i] = v[j];
v[j] = aux;
i++;
j--;
}
} while (i <= j);
if (esq < j) QuickSort(v,esq,j);
if (i < dir) QuickSort(v,i,dir);
}
21. 21
public static void QuickSort (int[] v, int esq, int dir) {
int i = esq;
int j = dir;
int pivo = v [ (esq+dir)/2 ];
int aux;
do {
while (v[i]<pivo && i<dir)
i++;
while (pivo<v[j] && j>esq)
j--;
if (i<=j) {
aux = v[i];
v[i] = v[j];
v[j] = aux;
i++;
j--;
}
} while (i <= j);
if (esq < j) QuickSort(v,esq,j);
if (i < dir) QuickSort(v,i,dir);
}
procura de maneira crescente
procura de maneira descendente
partição do vetor a ser analisada
parte responsável pelo processo de troca (ordenação)
Continue percorrendo o vetor procurando e ordenando
os elementos até que os contadores j e i se cruzem (i > j)
Repita recursivamente os
passos para as duas partes
procura elementos menor que o pivô na
primeira parte
procura elementos menor que o pivô na
segunda parte
inicio da ordenação
fim da ordenação
selecionando elemento pivô
24. 24
Demonstra como tempos de execução
são afetados pelo numero de itens
Resumo do tempo de execução dos algoritmos:
Média Pior Melhor
Bolha O(n2) O(n2) O(n)
Seleção O(n2) O(n2) O(n2)
Inserção O(n2) O(n2) O(n)
MergeSort O(n*log n) O(n*log n) O(n*log n)
QuickSort O(n*log n) O(n2) O(n*log n)
25. 25
Considere que a ordenação para n inteiros números leve
t segundos.
Calcule o tempo de ordenação para cem, mil, dez mil e
cem mil elementos para todos os algoritmos de
ordenação vistos: bubblesort, seleção, inserção,
mergesort e quicksort. Imprima na tela da seguinte
forma:
Obtenha valores aleatórios entre 0 e 500 para o vetor
desordenado.
26. 26
import java.util.Random;
public class Aleatorios {
public static void main(String[] args) {
Random gerador = new Random();
//imprime sequência de 10 números inteiros aleatórios
for (int i = 0; i < 10; i++)
System.out.println(gerador.nextInt(101));
/* Como o parâmetro do método é 101, os valores
gerados serão entre 0 e 100 */
}
}
Dica 1: Programa exemplo de como obter valores
aleatórios entre 0 e 100.
Dica 2: No desenvolvimento do programa não se esqueça
de manter uma cópia do vetor desordenado gerado.
Exemplo: for(i=0; i<n; i++) copia[i]=v[i];
Ordene somente a copia, não o vetor v.
27. 27
Dica 3: Programa exemplo de como calcular o tempo em
milissegundos em Java.
public class Tempo {
public static void main(String[] args) {
long tempoInicio;
// inicia contagem do tempo
tempoInicio= System.currentTimeMillis();
// imprime sequência de 0 a 999
for (int i = 0; i < 1000; i++)
System.out.print(i + " ");
/* finaliza contagem do tempo e imprime na tela o tempo
gasto para impressão da sequencia de 0 a 999 */
System.out.println("nTempo Total: " +
(System.currentTimeMillis()-tempoInicio) + " milisegundos");
}
}