Análise e Complexidade de Algoritmos Métodos de Ordenação - seleção e inserção - seleção e troca (bubble sort) - merge e quick sort - radix - hashing Prof. Rodrigo Rocha prof.rodrigorocha@yahoo.com http://www.bolinhabolinha.com Onde Estamos Ementa Revisão: Estrutura de dados;crescimento de funções; Indução matemática e métodos matemáticos. Medidas de complexidade, análise assintótica de limites de complexidades. Exemplos de análise de algoritmo iterativos e recursivos. Análise de desempenho de alguns algoritmos clássicos de busca e ordenação. Introdução aos principais paradigmas do projeto de algoritmos. Complexidade do Problema: Limites de Complexidade, Intratabilidade, Classes P, NP, problemas Np completos e NP-difíceis. 1
Introdução Atividade fundamental na computação Método de rearranjar um conjunto de dados em ordem crescente ou decrescente Métodos estudados: Seleção (Selection sort) Inserção (Insertion sort) Seleção e Troca (Bubble Sort) Intercalação (Merge Sort) Particionamento (troca) (QuickSort) Radix Ordenação Interna Simples Adequados para pequenos arquivos O(n2) Eficientes Arquivos maiores que requerem n(log n) Um dos métodos mais simples Funcionamento Seleção - Selection Sort Selecione o menor valor do vetor Troque com o item que está na 1. posição do vetor Repita esta operação para os n-1 itens restantes Depois repita para n-2, até restar apenas um elemento Animação http://www.cs.pitt.edu/~kirk/cs1501/animations/sort3.html 2
Seleção - Selection Sort Exemplo Seleção - Selection Sort Algortimo 3
Complexidade (números de troca) Seleção - Selection Sort Melhor caso entrada já ordenada O(n) Pior caso entrada na ordem inversa O(n 2 ) Caso médio O(n 2 ) Inserção - Insertion Sort Dividir os valores a serem ordenados em: coleção U de valores desordenados (a serem ordenados) coleção S de valores ordenados Remover um a um os valores de U e inserí-los em S Mantendo S ordenado Início: U = conjunto desordenado de valores S = vazio Termino: U = vazio S = conjunto ordenado de valores 4
Inserção - Insertion Sort Para ordenar n valores, no vetor A[0:n-1] Utilize A contendo subvetor S e U lado-a-lado S inicia no lado esquerdo de A U inicia no lado direito de A retire um valor V do final a esquerda de U criará um espaço entre S e U mova todos os valores em S que forem maiores que V um espaço a direita insira V no espaço remanescente em S Repetir até todos os valores em U estarem inseridos em S No final, S ocupa o mesmo espaço que A Inserção - Insertion Sort 5
Inserção - Insertion Sort Algoritmo Complexidade Melhor caso entrada já ordenada O(n) Pior caso entrada na ordem inversa O(n 2 ) Caso médio O(n 2 ) Inserção - Insertion Sort 6
Animação na web Inserção - Insertion Sort http://www.cs.oswego.edu/~mohammad/classes/c edu/ sc241/samples/sort/sort2-e.html http://www.ece.unb.ca/brp/lib/java/insertionsort/ http://www.oopweb.com/algorithms/documents/a nimatedalgorithms/volumeframes.html Funcionamento Seleção e Troca - Bubble sort Varrer o vetor V comparando os elementos adjascentes v[i], v[i+1] Se v[i]>v[i+1] troque v[i] por v[i+1] até nenhuma troca ser necessária Em cada passo maior valor é empurrado para o fim item(s) no final do vetor estão ordenados menor valor é movido uma posição a menos no final 7
Seleção e Troca - Bubble sort Vetor A =18 26 3 9 34 5 21 14 6 Passo 1: A =(18 26) 3 9 34 5 21 14 6 ok A = 18 (26 3) 9 34 5 21 14 6 troca A = 18 3 (26 9) 34 5 21 14 6 troca A = 18 3 9 (26 34) 5 21 14 6 ok A = 18 3 9 26 (34 5) 21 14 6 troca A = 18 3 9 26 5 (34 21) 14 6 troca A = 18 3 9 26 5 21 (34 14) 6 troca A = 18 3 9 26 5 21 14 (34 6) troca A = 18 3 9 26 5 21 14 6 34 Entre parênteses estão as comparações SubLista contém o último valor 34, e está ordenado Seleção e Troca - Bubble sort Passo 2: A = (18 3) 9 26 5 21 14 6 34 troca A = 3 (18 9) 26 5 21 14 6 34 troca A = 3 9 (18 26) 5 21 14 6 34 ok A = 3 9 18 (26 5) 21 14 6 34 troca A = 3 9 18 5 (26 21) 14 6 34 troca A = 3 18 9 5 21 (26 14) 6 34 troca A = 3 18 9 5 21 14 (26 6) 34 troca A = 3 18 9 5 21 14 6 (26 34) ok A = 3 18 9 5 21 14 6 26 34 sublista que contém os dois últimos valores 26 34 estão ordenados 8
Seleção e Troca - Bubble sort Passo 3: A = (3 18) 9 5 21 14 6 26 34 ok A = 3 (18 9) 5 21 14 6 26 34 troca A = 3 9 (18 5) 21 14 6 26 34 troca A = 3 9 5 (18 21) 14 6 26 34 ok A = 3 9 5 18 (21 14) 6 26 34 troca A = 3 9 5 18 14 (21 6) 26 34 troca A = 3 9 5 18 14 6 (21 26) 34 ok A = 3 9 5 18 14 6 21 (26 34) ok A = 3 9 5 18 14 6 21 26 34 sublista que contém os dois últimos valores 21 26 34 estão ordenados Depois do passo i, o último valor de i está ordenado Seleção e Troca - Bubble sort (Após) Passo 4: A =3 5 9 14 6 18 21 26 34 (Após) Passo 5: A =3 5 9 6 14 18 21 26 34 (Após) Passo 6: A = 3 5 6 9 14 18 21 26 34 (Após) Passo 7: A = 3 5 6 9 14 18 21 26 34 Terminado!!! nenhuma troca é necessária 9
Seleção e Troca - Buble Sort static void bubblesort(int vet[]) { int passo,j,temp; p; //contador dos passos de 1 até o tamanho do vetor for (passo=1;passo<vet.length;passo++) // passa por todos comparando o menor for (j=0;j<vet.length-passo;j++) if (vet[j]>vet[j+1]) { // troca os elementos temp = vet[j+1]; vet[j+1] = vet[j]; vet[j]=temp; } } Seleção e Troca - Bubble sort Número de comparações Para 9 valores: 8 primeiro passo, 7 no segundo, 6 no terceiro,. 8+7+6+5+4+3+2+1 = 36 (comparações) Para n valores: (n-1) primeiro passo, (n-2) segundo passo, (n-1) + (n-2) +. + 1 = n * (n+1)/2 (comparações) Número de comparações: n * (n+1)/2 = (n 2 + n)/2 10
Melhor Caso vetor já ordenado Seleção e Troca - Bubble sort (n-1) comparações, nenhuma troca Caso médio metade do tempo n(n+1)/4 proporcional a n 2 Pior Caso vetor ordenado decrescente uma troca por comparação n(n+1)/2 = O(n 2 ) Animação na web Seleção e Troca - Bubble sort http://www.cs.oswego.edu/~mohammad/classes/c sc241/samples/sort/sort2-e.html http://www.ece.unb.ca/brp/lib/java/bubblesort/ http://www.cosc.canterbury.ac.nz/people/mukund an/dsal/bsort.html l 11
Merge sort Refinamento da estretégia de dividir para conquistar Para ordenar n valores em um vetor A[0:n-1], na ordem ascendente: 1. Dividir a seqüência A em duas metades, esquerda E e direita D 2. MergeSort a seqüência esquerda E 3. MergeSort a seqüência direira D Unir as seqüências direita e esquerda em um resultado S Utilizar recursividade para ordenar os dois lados O coração do MergeSort é o passo de união Passo de união Merge sort Assumimos duas seqüências ordenadas D e E Para juntar os valores de D e E em uma nova seqüência ordenada S repetidamente 1. compare os valores iniciais de D e E 2. coloque o menor em S 3. (Se uma das seqüências estiver vazia, copiar os elementos restantes dentro de S Resultado: S contém todos os elementos de D e E ordenados 12
Merge sort MergeSort A =18 26 3 9 34 5 21 14 6 Divide A: E = 18 26 3 9 e D =34 5 21 14 6 MergeSort E: Divide E: EE = 18 26 e ED =3 9 MergeSort EE: Divide EE: EEE = 18 e EED = 26 MergeSort EEE: ( já está ordenado) MergeSort EED: (já está ordenado) Merge 18 (EEE ordenado) e 26 (EED ordenado): Resultado: 18 26 MergeSort ED:... Resultado: 3 9 Merge 18 26 (EE ordenado) e 3 9(ED ordenado): Resultado: 3 9 18 26 MergeSort D:... Resultado: 5 6 14 21 34 Merge 3 9 18 26(E ordenado) e 5 6 14 21 34(D ordenado): Resultado: 3 5 6 9 14 18 21 26 34 Merge sort - exemplo 13
Merge sort - exemplo Merge sort - exemplo 14
Merge sort - exemplo Merge sort - exemplo 15
void mergesort(int a[ ], int low, int high) { if(low == high) return; int length = high-low+1; int pivot = (low+high) / 2; mergesort(a, low, pivot); mergesort(a, pivot+1, high); int working[ ] = new int[length]; for(int i = 0; i < length; i++) working[i] = a[low+i]; int m1 = 0; int m2 = pivot-low+1; for(int i = 0; i < length; i++) { if(m2 <= high-low) if(m1 <= pivot-low) if(working[m1] > working[m2]) a[i+low] = working[m2++]; else a[i+low] = working[m1++]; else a[i+low] = working[m2++]; else a[i+low] = working[m1++]; } } Merge Sort Merge sort Estratégia Dividir um vetor A de n elementos em duas metades (vetores) E[0:meio] e D[meio+1:n-1] Combinar as metades ordenadas E e D unindo-as em um único resultado ordenado Atenção requer um vetor adicional de tamanho igual ao que irá ser ordenado se somente o vetor original ocupa toda memória, merge sort não irá funcionar se você tem bastante espaço, merge sort é a melhor escolha Complexidade Caso médio O(n log n) Pior caso O(n log n) 16
Animações na web Merge sort http://www.geocities.com/siliconvalley/program/2 864/File/Merge1/mergesort.html http://wwwcse.uta.edu/~holder/courses/cse2320/lectures/ap plets/sort1/mergesort_df.html 1-) Simular o processo do algoritmo de ordenação Merge Sort para o seguinte conjunto de valores: 10,3,6,12,33,21,56,2,13,1 Merge Sort 2-) Implementar o algoritmo de merge sort e testá-lo. 17
Quick sort QuickSort foi descoberto em 1962. Refinamento do algoritmo de dividir para conquistar Para ordenar n valores em um vetor A[0:n-1], na ordem ascendente: 1. Particionar a seqüência A em direita D e esquerda E utilizando um valor de A como pivô 2. QuickSort a porção esquerda E. 3. QuickSort a porção direita D. Utilizar recursividade para ordenar os dois lados Até uma seqüência de 1 elemento, que está ordenada o coração do QuickSort é o passo de Particionar partir o vetor em dois sub vetores, tal que todos os elementos do primeiro sejam menores ou iguais a todos os elementos do segundo Particionando Particionamento dos dados Para particionar os dados, dividimos em dois grupos selecionamos um pivô podemos utilizar diversas técnicas (exemplo: meio do vetor) percorro o vetor de baixo para cima até achar um valor que seja maior que o pivô percorro o vetor de cima para baixo até achar um valor que seja menor que o pivô troca-se os dois elementos (aquele que não era menor que o pivô com aquele que não era maior que o pivô) término = quando os percursos se cruzarem: dois grupos, um abaixo do pivô, com elementos menor que este outro acima do pivô, com elementos maiores que este 18
Quick sort - particionamento Quick sort - particionamento 19
Quick sort - particionamento Quick sort - particionamento 20
Quick sort - particionamento Exemplo 21
Quick sort Algoritmo void quicksort (int[] a, int lo, int hi) { // lo é o índice mais baixo, hi é o índice mais alto // da região do vetor que irá ser ordenada int i=lo, j=hi, h; int x=a[(lo+hi)/2]; // particionamento do { while (a[i]<x) i++; while (a[j]>x) j--; if (i<=j) { h=a[i]; a[i]=a[j]; a[j]=h; i++; j--; } } while (i<=j); // recursão if (lo<j) quicksort(a, lo, j); if (i<hi) quicksort(a, i, hi); } Quick sort Complexidade melhor caso (a) cada particionamento produz duas partes de tamanhos iguais O(n log n) - log n cada metade Caso médio O(n log n) Pior Caso (c) Pivo é o maior ou menor valor da partição Passo de particionamento separa n valores em grupos de um valor, e os grupos contém n-1 valores)o(n2) QuickSort é muito sensível a escolha do Pivo 22
Animações na web http://www.cs.oswego.edu/~mohammad/classes/c edu/~mohammad/classes/c sc241/samples/sort/sort2-e.html http://www- cse.uta.edu/~holder/courses/cse2320/lectures/ap / / t / plets/quicksort/ Radix sort Rearranjar o vetor baseado na representação inteira dos dígitos individuais inteiros caracteres decimais (preparados) datas dois tipos least significant digit (LSD) dígito menos significativo most significant digit (MSD) dígito mais significativo 23
Radix sort Processo do LSD Pegue o último digito mais significativo de cada chave Agrupe as chaves baseado no dígito, mantendo a ordem original das chaves repita o processo para os outros dígitos mais significativos Exemplo Original, lista desordenada: 170, 45, 75, 90, 2, 24, 802, 66 Ordenando pelo último digito (unidade) 170, 90, 2, 802, 24, 45, 75, 66 Atenção: 2 está antes do 802, pois ele ocorre antes na lista original. Assim como o 170 e 90. Ordenando o próximo dígito (dezena) 2, 802, 24, 45, 66, 170, 75, 90 Ordenando pelo próximo dígito (centena) 2, 24, 45, 66, 75, 90, 170, 802 Complexidade temos Radix sort n total de elementos m o valor máximo de um conjunto de elementos exemplo sistemá decimal de 0 a 9, logo 10 digitos m=10 p é o número de iterações, depende da quantidade de dígitos, de 0 a 999 p=3 O(m*p) e O(n*p) = O(p(n+m)) m e p são pequenos no caso de sistema decimal m=10 e p<=10 O(n) 24
Radix sort Animações na web http://wwwcse.uta.edu/~holder/courses/cse5311/lectures/ap plets/radix/radixsort.html http://www.cse.iitk.ac.in/users/dsrkg/cs210/applet s/sortingii/radixsort/radixsort.html http://www.cs.umass.edu/~immerman/cs311/appl ets/vishal/radixsort.html Exercícios Modifique o programa selection sort para sempre jogar o maior elemento para o final, ao invés do menor para o começo. A complexidade mudou? Justifique. Modifique o programa selection sort para ordenar de forma decrescente 25
Exercícios 1-) Considerando os vetores abaixo: a-) [ 10, 1, 9, 2, 8, 3 ] b-) [ 8,9,7,9,3,2,3,8,4,6 ] c-) [ 1,4,6,8,12,11 ] d-) [ 13,33,43,53,63 ] Desenhe a seqüência de passos realizados para ordená-los, utilizando os métodos de busca insertion sort e bubble sort. Qual a complexidade de cada ordenação para cada vetor? 2-) Se para cada comparação feita no algoritmo de ordenação bubble sort, você realiza-se uma busca seqüencial, com que complexidade ficaria este novo algoritmo? 3-) Se a busca implementada no exercício 2 fosse binária, a complexidade mudaria? Justifique. 4-) Um programador desconfiado, achou melhor implementar em cada iteração do insertion sort (no vetor parcialmente ordenado S), uma verificação, para isso, executa o procedimento de ordenação bubble sort na parte ordenada pelo insertion sort. Você acredita que foi uma boa escolha? Justifique? Exercícios 1-) Simular a ordenação por quick sort no seguinte conjunto de valores: 7, 1, 3, 9, 8, 4, 2, 7, 4, 2, 3, 5. 2-) Implementar o algoritmo de quick sort e testá-lo. 26
Exercício Radix sort Ordenar utilizando radix sort os seguintes conjuntos: a-) 45 93 38 74 39 32 72 14 92 5 91 66 0 1 2 3 4 5 6 7 8 9 Exercício Radix sort Ordenar utilizando radix sort os seguintes conjuntos: b-) 111 12 11 1 33 22 112 2 96 55 14 66 0 1 2 3 4 5 6 7 8 9 27
Radix sort Exercício c-) Como ficaria a implementação do Radix para ordenação de palavras? Dê um exemplo de ordenação de palavras com até 3 letras. Como ficou a complexidade, ela mudou? Livro texto Bibliografia ZIVIANI, Nivio. Projeto de Algoritmos : com implementação em Pascal e C.. 2ª ed. São Paulo: Pioneira Thomson Learning, 2004. VELOSO, Paulo A. S.. Estrutura de Dados. 1ª ed. São Paulo: Campus, 1983. CORMEN, Thomas H. Algoritmos : teoria e prática. 1ª ed. Rio de Janeiro: CAMPUS, 2002. Complementar SCHILDT, Herbert. C Completo e Total. 3ª ed. São Paulo: Pearson Education, 2005. Education, 2005. CELES, Waldemar; CERQUEIRA, Renato. Introdução a Estruturas de Dados : com técnicas de programação em C. 4ª ed. Rio de Janeiro: Elsevier, 2004 WIRTH, Niklaus. Algoritmos e Estruturas de Dados. 1ª ed. Rio de Janeiro: LTC, 1989 TENENBAUM, Aaron M; SOUZA, Tereza Cristina Félix de. Estruturas de Dados usando C. 1ª ed. São Paulo: Makron Books,1995. 28