Capítulo 14 Ordenação e pesquisa Alguns algoritmos de ordenação e pesquisa Medição do tempo de execução de um programa Bubblesort • Identifica os pares de elementos contíguos que não estão na ordem correcta e troca-os. É o método mais simples de ordenação mas não é eficiente. A sua complexidade é proporcional ao quadrado do número de elementos do vector 11 9 17 5 12 9 11 17 5 12 9 11 9 11 5 12 17 9 5 11 12 17 9 5 11 12 17 5 9 11 12 17 5 17 12 9 11 5 12 17 não houve trocas ! 5 9 11 12 17 5 9 11 12 17 Introdução à Programação 5 9 2007/08 11 12 17 A. Lopes Bubblesort /** Sorts the array int[] vec by the bubblesort method. */ public void bubbleSort() { for (int i = vec.length-1; i > 0 ; i--) e se não houver trocas { para um dado i ? for (int j = 0; j < i - 1; j++) if (vec[j] > vec[j+1]) { // then swap vec[i] with vec[j] int temp = vec[i]; vec[i] = a[j]; vec[j] = temp; Melhoria: parar o processo logo que se } detecte que, para uma dada passagem pelo } vector, não foram efectuadas quaisquer trocas } Introdução à Programação 2007/08 A. Lopes Ordenação por selecção linear • Selecciona o menor elemento do sub-vector ainda não ordenado e troca-o com o primeiro. É um algoritmo considerado lento. A sua complexidade é proporcional ao quadrado do número de elementos do vector • no início, o sub-vector ordenado tem comprimento 0 11 9 17 • procura o menor e troca com o 1º elemento 5 9 17 11 12 • pesquisa o próximo menor. Já está na posição correcta 5 9 17 11 12 • pesquisa o próximo menor e troca com o 1º elemento do sub-vector ainda não ordenado 5 9 11 17 12 5 9 11 12 17 5 9 11 12 17 • repete o processo até que o número de elementos por ordenar seja 1 Introdução à Programação 2007/08 5 A. Lopes 12 Ordenação por selecção linear /** Sorts the array int[] vec by the selection method. */ public void selectionSort() { for (int i = 0; i < vec.length - 1; i++) { // finds the smallest element in a tail range [i,vec.length-1] int minPos = i; for (int j = i + 1; j < vec.length; j++) if (vec[j] < vec[minPos]) minPos = j; // swap vec[i] with vec[minPos] int temp = vec[i]; vec[i] = a[minPos]; vec[minPos] = temp; } } Introdução à Programação 2007/08 A. Lopes Ficheiro SelectionSorter.java Introdução à Programação 2007/08 A. Lopes Ficheiro SelectionSorterTester.java Introdução à Programação 2007/08 A. Lopes Ficheiro ArrayUtil.java Introdução à Programação 2007/08 A. Lopes Ficheiro StopWatch.java Introdução à Programação 2007/08 A. Lopes Medição do tempo de execução de um algoritmo • Objectivo: medir o tempo de execução do algoritmo, excluindo o tempo que demora a carregar o programa e o tempo que demora a escreve o resultado • Criar uma classe StopWatch • métodos para iniciar, parar e devolver o tempo que decorreu • utilização do método System.currentTimeMillis • Criar um objecto da classe StopWatch e • iniciar antes da execução do algoritmo a medir • parar imediatamente após a respectiva execução • ler o tempo que decorreu Introdução à Programação 2007/08 A. Lopes Ficheiro SelectionSortTimer.java Introdução à Programação 2007/08 A. Lopes Desempenho da ordenação por selecção vectores de várias dimensões Exemplo: n ms 10,000 772 20,000 3,051 30,000 6,846 40,000 12,188 50,000 19,015 60,000 27,359 Ao duplicar o tamanho do vector, mais do que duplica o tempo para a respectiva ordenação Introdução à Programação 2007/08 A. Lopes Ordenação por inserção sequencial • Considera que, se um sub-vector, formado pelos primeiros elementos do vector dado, já estiver ordenado, basta inserir ordenadamente o elemento seguinte nesse sub-vector Introdução à Programação 3 7 5 8 1 3 7 5 8 1 3 7 5 8 1 3 5 7 8 1 3 5 7 8 1 1 3 5 7 8 2007/08 A. Lopes Ordenação por inserção sequencial /** Sorts the array int[] vec by the insertion method. */ public void insertionSort() { for (int i = 1; i < vec.length; i++) { int next = vec[i]; // move all larger elements up int j = i; while (j > 0 && vec[j-1] > next) { vec[j] = vec[j-1] j--; } // insert the element vec[j] = next; } } Introdução à Programação 2007/08 3 7 5 8 1 3 7 5 8 1 3 7 5 8 1 3 5 7 8 1 3 5 7 8 1 1 3 5 7 8 A. Lopes Ficheiro InsertionSorter.java Introdução à Programação 2007/08 A. Lopes Merge sort ordenação recursiva de vectores • Estratégia: 1. Sub-dividir o vector em duas partes (ao meio) 2. Ordenar recursivamente cada uma das partes, seguindo a estratégia 3. Fundir as duas partes já ordenadas 4 4 4 3 3 3 4 9 3 1 9 9 9 1 1 3 4 1 3 1 9 4 1 9 3 4 1 5 7 8 5 7 7 7 8 8 8 5 Introdução à Programação 5 7 7 8 5 7 8 9 8 2007/08 A. Lopes Comparação de desempenho merge sort e ordenação por selecção n merge sort (ms) selecção (ms) 10,000 31 772 20,000 47 3,051 30,000 62 6,846 40,000 80 12,188 50,000 97 19,015 60,000 113 27,359 merge sort algoritmo de O (n log(n) ) ordenação por selecção algoritmo de O (n2 ) Introdução à Programação 2007/08 A. Lopes Pesquisa em vectores • Pesquisa linear (ou sequencial) e se o vector estiver ordenado ? • analisa todos os elementos do vector até encontrar um/o elemento que pesquisa, ou até atingir o fim do vector. No máximo, faz n testes de comparação, sendo n a dimensão do vector • Pesquisa binária (ou dicotómica) - num vector ORDENADO • determina se o valor a pesquisar está no meio do vector. Se não estiver, repete o processo numa das partes (esquerda ou direita) do vector e assim sucessivamente. A complexidade do algoritmo é logarítmica (log n) 2 4 6 6 8 10 13 16 19 21 27 56 57 58 65 67 70 2 4 6 6 8 10 13 16 19 21 27 56 57 58 65 67 70 2 4 6 6 8 10 13 16 19 21 27 56 57 58 65 67 70 2 4 6 6 8 10 13 16 19 21 27 56 57 58 65 67 70 2 4 6 6 8 10 13 16 19 21 27 56 57 58 65 67 70 Introdução à Programação 2007/08 pesquisa 12 ... não encontra 12 A. Lopes Ficheiro LinearSearcher.java Introdução à Programação 2007/08 A. Lopes Ficheiro BinarySearcher.java Introdução à Programação 2007/08 A. Lopes Visualização de algoritmos de ordenação applet da Universidade de Ottawa http://www.site.uottawa.ca/~stan/csi2514/applets/sort/sort.html Introdução à Programação 2007/08 A. Lopes