Capítulo 2 - Algoritmos elementares de ordenação

Documentos relacionados
Algoritmos e Estruturas de Dados LEE 2013/2014. popular devido à facilidade de implementação e eficiência

QuickSort. Algoritmos e Estruturas de Dados Verão Cátia Vaz 1

Quicksort [1] Quicksort [2]

AED Algoritmos e Estruturas de Dados LEEC /2006. Algoritmos de Ordenação 1ª parte

Algoritmos de Ordenação

Métodos de Ordenação

ALGORITMOS DE ORDENAÇÃO

Projeto e Análise de Algoritmos

Métodos de Ordenação Parte I

6. Pesquisa e Ordenação

QuickSort. Estrutura de Dados II Jairo Francisco de Souza

BCC202 - Estrutura de Dados I

Quick Sort. Considerações Sobre Algoritmos de Ordenação. Estagiário PAE: Jesimar da S. Arantes Professor: ClaudioQuick F. M.

Ordenação e Pesquisa

MAC121 ALGORITMOS E ESTRUTURAS DE DADOS I 2O. SEMESTRE DE 2017

heapsort (int *x, int n) { int i, e, s, f, aux; /*fase de pré-processamento - cria heap inicial*/ for (i=1; i<n; i++) { e = x[i]; s = i; f = (s-1)/2;

AED2 - Aula 11 Problema da separação e quicksort

5. Análise de Complexidade de Algoritmos. João Pascoal Faria (versão original) Ana Paula Rocha (versão 2003/2004) Luís Paulo Reis (versão 2005/2006)

MÉTODOS DE ORDENAÇÃO. Introdução à Programação SI2

Análise de complexidade

Ordenação. Insertion Sort

Métodos de Ordenação: Selection, Insertion, Bubble, Merge (Sort)

ESTRUTURAS DE DADOS E ALGORITMOS ALGORITMOS DE ORDENAÇÃO POR COMPARAÇÃO - II

Bubble Sort. Tempo total O(n 2 )

BCC202 - Estrutura de Dados I

Ordenação: QuickSort. Prof. Túlio Toffolo BCC202 Aula 15 Algoritmos e Estruturas de Dados I

Algoritmos de ordenação Quicksort

Análise e Síntese de Algoritmos. Revisão CLRS, Cap. 7-10

Algoritmos e Estruturas de Dados. Décima sexta aula: Quicksort

Estruturas de Dados 2

Algoritmos e Estrutura de Dados. Algoritmos Prof. Tiago A. E. Ferreira

Algoritmos de Ordenação: QuickSort

Pedro Ribeiro 2014/2015

Vectores: Algoritmos de Ordenação. Algoritmos e Estruturas de Dados 2008/2009

BCC202 - Estrutura de Dados I

Ordenação de Vectores

Estrutura de Dados. Algoritmos de Ordenação. Prof. Othon M. N. Batista Mestre em Informática

Projeto e Análise de Algoritmos Aula 4: Dividir para Conquistar ou Divisão e Conquista ( )

Ordenação. Prof. Jonas Potros

É interessante comparar algoritmos para valores grandes de n. Para valores pequenos de n, mesmo um algoritmo ineficiente não custa muito para ser

Algoritmos de Ordenação. Profº Carlos Alberto T. Batista

Métodos de ordenação. Bubble sort:

Classificação por Seleção - selection sort

Algoritmos de Ordenação

Classificação e Pesquisa Aula 6 Métodos de Ordenação: ShellSort e QuickSort. Prof. Esp. Pedro Luís Antonelli Anhanguera Educacional

Ordenação. Prof. Túlio A. M. Toffolo Prof. Marco Antonio M. Carvalho BCC402 Aula 04 Algoritmos e Programação Avançada

Algoritmos de Ordenação

INF1007: Programação 2 6 Ordenação de Vetores. 01/10/2015 (c) Dept. Informática - PUC-Rio 1

5. Algoritmos de Ordenação

O mais leve e o mais pesado Algoritmos de Ordenação

Extra- Algoritmos de Ordenação

Ordenação: HeapSort. Prof. Túlio Toffolo BCC202 Aula 17 Algoritmos e Estruturas de Dados I

Edital de Seleção 032/2016 PROPESP/UFAM. Prova de Conhecimento. Caderno de Questões

Existem duas categorias de algoritmos de ordenação: Os algoritmos de ordenação são avaliados de acordo com os seguintes critérios:

Análise de Algoritmos Estrutura de Dados II

Quick Sort. Considerações Sobre Algoritmos de Ordenação. Estagiário PAE: Jesimar da S. Arantes Professor: Claudio Quick F. M.

Análise de Complexidade de Algoritmos

Aula 1. Teoria da Computação III

Os métodos de ordenação que ordenam os elementos in situ podem ser classificados em três principais categorias:

QuickSort CI/2015. Análise e Projeto de Algoritmos. - Prof. Lucídio A. F. Cabral

BUSCA EM ARRAYS. Prof. André Backes. Ato de procurar por um elemento em um conjunto de dados

Recursividade. Objetivos do módulo. O que é recursividade

Arquivos Sequenciais. Estruturas de Dados II Vanessa Braganholo

ALGORITMOS E ESTRUTURAS DE DADOS CES-11 Prof. Paulo André Castro Sala 110 Prédio da Computação IECE - ITA

Aula 13: Ordenação - Heapsort. Bruno Hott Algoritmos e Estruturas de Dados I DECSI UFOP

ANÁLISE DE COMPLEXIDADE DOS ALGORITMOS

ALGORITMOS AVANÇADOS. UNIDADE III Algoritmo de Ordenação por Intercalação (Mergesort) Luiz Leão

Divisão e conquista. Eficiência de divisão e conquista

Edital de Seleção 024/2017 PROPESP/UFAM. Prova de Conhecimento. Caderno de Questões

Quicksort. David Menotti Algoritmos e Estruturas de Dados II DInf UFPR

Algoritmos e Estruturas de Dados I1 Prof. Eduardo 1

Universidade Estadual de Mato Grosso do Sul Bacharelado em Ciência da Computação Algoritmos e Estruturas de Dados II Prof. Fabrício Sérgio de Paula

Algoritmos de ordenação: Bucketsort, Radixsort e Seleção

Métodos de Ordenação Parte 2

Programação de Computadores Ordenação de Arranjos

Capítulo 14. Ordenação e pesquisa. Bubblesort. Alguns algoritmos de ordenação e pesquisa Medição do tempo de execução de um programa

Transcrição:

Capítulo 2 - Algoritmos elementares de ordenação ISEL/LEIC - 2007/2008 2º ano, 1º Semestre * Estes acetatos foram parcialmente adaptados dos acetatos de AED da LEEC do Instituto Superior Técnico Prof. Rui Gustavo Crespo Nuno Leite AED: Algoritmos e Estruturas de Dados Semestre de Inverno 2007/08 http://www.deetc.isel.ipl.pt/programacao/aed/

Algoritmos elementares de ordenação Começaremos o nosso estudo com algoritmos elementares de ordenação: Selection sort, Insertion sort, Bubble sort e Shell sort Porquê estudar algoritmos elementares de ordenação? Razões de ordem prática Fáceis de codificar e por vezes suficientes Rápidos/Eficientes para problemas de dimensão média e por vezes os melhores em certas circunstâncias Razões pedagógicas Bom exemplo para aprender terminologia, compreender contexto dos problemas e bom princípio para desenvolvimento de algoritmos mais sofisticados Alguns são fáceis de generalizar para métodos mais eficientes Importante para compreensão das regras de "funcionamento" LEIC AED Inverno 2007/08 Algoritmos de ordenação 2

Contexto e regras básicas (1) Objectivo estudar métodos de ordenação de ficheiros de dados em que cada elemento (item) é caracterizado por uma chave (key) chaves são usadas para controlar a ordenação objectivo é rearranjar os dados de forma a que as chaves estejam ordenadas de forma pré-definida (numérica ou alfabética, por exemplo) Metodologia características específicas de cada item ou chave podem ser diferentes mas conceito abstracto é o mais importante utilizaremos operações abstractas nos dados: comparação, troca LEIC AED Inverno 2007/08 Algoritmos de ordenação 3

Contexto e regras básicas (2) Metodologia começaremos por estudar ordenação em arrays consideraremos primeiro ordenação de sequências de inteiros apresentaremos posteriormente uma implementação genérica Tempo de execução usualmente proporcional ao número de comparações número de movimentações/trocas (ou ambos) LEIC AED Inverno 2007/08 Algoritmos de ordenação 4

Programa de teste de algoritmos de ordenação public class IntArraySort { private static boolean less(int x, int y) { return x < y; } private static void exch(int[] a, int i, int j) { int aux = a[i]; a[i] = a[j]; a[j] = aux; } private static void lessexch(int[] a, int i, int j) { if (less(a[i], a[j])) exch (a, i, j); } // Selection Sort private static void selectionsort(int[] a, int l, int r) {... } // Insertion Sort private static void insertionsort(int[] a, int l, int r) {... } // Bubble Sort private static void bubblesort(int[] a, int l, int r) {... }... LEIC AED Inverno 2007/08 Algoritmos de ordenação 5

Programa de teste de algoritmos de ordenação... public static void sort(int[] a, int l, int r) { selectionsort(a, l, r); } public static void main(string[] args) { int n = 50; int a[] = new int[n]; for (int i = 0; i < n; ++i) { // random gera números no intervalo [0.0; 1.0[ a[i] = (int) (Math.random()*100); } sort(a, 0, n-1); // Ordenar array for (int i = 0; i < n; ++i) // Imprimir array System.out.print(a[i] + " "); } } // classe IntArraySort LEIC AED Inverno 2007/08 Algoritmos de ordenação 6

Nomenclatura (1) Tipos de Algoritmos de Ordenação não adaptativos: sequência de operações independente da ordenação original dos dados interessantes para implementação em hardware adaptativos: sequência de operações dependente do resultado de comparações (operação "less") a maioria dos que estudaremos Parâmetro de interesse é o desempenho, i.e. tempo de execução algoritmos básicos: N 2 para ordenar N itens mas por vezes os melhores para N pequeno algoritmos avançados: N log N para ordenar N itens p.ex., Quicksort, Mergesort, Heapsort LEIC AED Inverno 2007/08 Algoritmos de ordenação 7

Nomenclatura (2) Olharemos também para os recursos de memória necessários ordenação "in-place" ou utilizando memória adicional Definição: um algoritmo de ordenação é dito estável se preserva a ordem relativa dos itens com chaves repetidas ex: ordenar lista de alunos por ano de graduação quando esta já está ordenada alfabeticamente por nome é usualmente possível estabilizar um algoritmo alterando a sua chave (tem custo adicional) algoritmos básicos são quase todos estáveis, mas poucos algoritmos avançados são estáveis LEIC AED Inverno 2007/08 Algoritmos de ordenação 8

Exemplo: Algoritmo estável vs não estável Ordenado pela 1ª chave (nome) Afonso 1 Beatriz 2 Bruno 4 João 2 José 4 Mariana 2 Mário 3 Matilde 3 Sílvia 1 Tânia 4 Após ordenação pela segunda chave (número) algoritmo não estável Afonso 1 Sílvia 1 Mariana 2 João 2 Beatriz 2 Matilde 3 Mário 3 Tânia 4 Bruno 4 José 4 Após ordenação pela segunda chave (número) algoritmo estável Afonso 1 Sílvia 1 Beatriz 2 João 2 Mariana 2 Mário 3 Matilde 3 Bruno 4 José 4 Tânia 4 LEIC AED Inverno 2007/08 Algoritmos de ordenação 9

Nomenclatura (3) Definição: um algoritmo de ordenação é dito interno, se o conjunto de todos os dados a ordenar couber na memória; caso contrário é dito externo ex: ordenar dados lidos de disco é ordenação externa Distinção muito importante: ordenação interna pode aceder a qualquer dado facilmente ordenação externa tem de aceder a dados de forma sequencial (ou em blocos) Vamos estudar fundamentalmente ordenação interna LEIC AED Inverno 2007/08 Algoritmos de ordenação 10

Nomenclatura (4) Definição: um algoritmo de ordenação é dito directo se os dados são acedidos directamente nas operações de comparação e troca; caso contrário é dito indirecto Exemplo de algoritmo indirecto: se a chave for pequena e cada dado for "grande (por exemplo o nome completo de um aluno, mais morada, número de BI, etc.) nestes casos não convém estar a trocar os elementos é dispendioso basta trocar a informação correspondente aos seus índices array de índices/ponteiros em que o primeiro indica o menor elemento, etc. LEIC AED Inverno 2007/08 Algoritmos de ordenação 11

Exemplo: Ordenação indirecta Em Java, a ordenação de elementos de tipo básico é feita de forma directa, e a ordenação de objectos é realizada de forma indirecta, dado que estes são manipulados por referência A figura ao lado ilustra o conteúdo dum array a ser ordenado, contendo referências para objectos com chaves E X A M P L E, nesta ordem. Após a ordenação das referências, o array passa a referir os objectos na ordem A E E L M P X LEIC AED Inverno 2007/08 Algoritmos de ordenação 12

Ordenação por selecção - Selection Sort Algoritmo: procurar menor elemento e trocar com o elemento situado na 1.ª posição procurar 2.º menor elemento e trocar com o elemento situado na 2.ª posição proceder assim até ordenação estar completa a sombreado, indicam-se os elementos já ordenados LEIC AED Inverno 2007/08 Algoritmos de ordenação 13

Implementação private static void selectionsort(int[] a, int l, int r) { int min; for (int i = l; i < r; ++i) { min = i; for (int j = i+1; j <= r; ++j) if (less(a[j], a[min])) min = j; exch(a, i, min); } } LEIC AED Inverno 2007/08 Algoritmos de ordenação 14

Selection Sort -Análise Ciclo interno apenas faz comparações troca de elementos é feita fora do ciclo interno cada troca coloca um elemento na sua posição final Número de trocas é N-1 (porque não N?) tempo de execução dominado pelo número de comparações! Propriedade: Selection sort usa aproximadamente N trocas e N 2 /2 comparações Demonstração: para cada item i de 1 a N-1 há uma troca e N-i comparações (ver sombreados no exemplo) Logo há N-1 trocas e (N-1) + (N-2) +... + 2 + 1 = N(N-1)/2 comparações LEIC AED Inverno 2007/08 Algoritmos de ordenação 15

Selection Sort -Análise Factos: desempenho é independente da ordenação inicial dos dados; a única coisa que depende desta ordenação é o número de vezes que min éactualizado quadrático no pior caso (dados ordenados de forma inversa) N log N em média (dados ordenados aleatoriamente) Algoritmo não adaptativo Ordenar um ficheiro já ordenado demora tanto tempo como ordenar um ficheiro ordenado aleatoriamente! LEIC AED Inverno 2007/08 Algoritmos de ordenação 16

Ordenação Síntese da Aula 1 Introdução ao problema da ordenação de dados Simplicidade do problema facilita a compreensão de conceitos chave em algoritmos Problema de grande aplicação Definição das regras base e interface de utilização operações elementares relevantes Definições e propriedades gerais Ordenação por Selecção Selection sort Descrição Exemplo de aplicação Análise de eficiência LEIC AED Inverno 2007/08 Algoritmos de ordenação 17

Ordenação por inserção - Insertion Sort Ideia: considerar os elementos um a um e inseri-los no seu lugar entre os elementos já tratados (mantendo essa ordenação) ex: ordenar cartas de jogar inserção implica arranjar novo espaço ou seja mover um número elevado de elementos uma posição para a direita inserir os elementos um a um começando pelo da 1ª posição LEIC AED Inverno 2007/08 Algoritmos de ordenação 18

Insertion Sort - Funcionamento Durante a primeira passagem de Insertion sort, o S na segunda posição é maior que A, não sendo necessário mover-se. Na segunda passagem, quando é encontrado o O na terceira posição, este é trocado com o S colocando A O S em ordem, e assim por diante. Elementos não sombreados e não assinalados com um círculo, são aqueles que são movidos uma posição para a direita LEIC AED Inverno 2007/08 Algoritmos de ordenação 19

Implementação private static void insertionsort1(int[] a, int l, int r) { for (int i = l+1; i <= r; ++i) { for (int j = i; j > l; --j) lessexch(a, j, j-1); } } LEIC AED Inverno 2007/08 Algoritmos de ordenação 20

Insertion Sort - Comentários Elementos à esquerda do índice corrente estão ordenados mas não necessariamente na sua posição final podem ainda ter de ser deslocados para a direita para dar lugar a elementos menores encontrados posteriormente Implementação da ordenação por inserção na pág. anterior é ineficiente código é simples, claro, mas pouco eficiente; pode ser melhorado ilustra bom raciocínio: encontrar solução simples estudar o seu funcionamento melhorar desempenho através de pequenas transformações LEIC AED Inverno 2007/08 Algoritmos de ordenação 21

Insertion Sort - Melhorar desempenho Demasiadas operações de comparação/troca (lessexch) podemos parar se encontramos uma chave que não é maior que a do item a ser inserido (array está ordenado à esquerda) podemos sair do ciclo interno se less(a[j-1], a[j]) éverdadeira modificação torna o algoritmo adaptativo aumenta desempenho aproximadamente por um factor de 2 Passa a haver duas condições para sair do ciclo mudar para um ciclo while remover instruções irrelevantes lessexch não é o melhor processo de mover vários dados uma posição para a direita LEIC AED Inverno 2007/08 Algoritmos de ordenação 22

Insertion Sort - Versão adaptativa private static void insertionsort2(int[] a, int l, int r) { for (int i = l+1; i <= r; ++i) { int v = a[i]; int j = i; while (j >= l+1 && less(v, a[j-1])) { a[j] = a[j-1]; --j; } a[j] = v; } } LEIC AED Inverno 2007/08 Algoritmos de ordenação 23

Insertion Sort -Análise Propriedade: Insertion sort usa aproximadamente N 2 /4 comparações e N 2 /4 pseudo-trocas (translações ou movimentos) no caso médio e o dobro destes valores no pior caso Demonstração: Fácil de ver graficamente; elementos abaixo da diagonal são contabilizados (todos no pior caso) Para dados aleatórios é expectável que cada elemento seja colocado aproximadamente a meio para trás pelo que apenas metade dos elementos abaixo da diagonal devem ser contabilizados Factos: Quando a sequência a ordenar se encontra parcialmente ordenada, o Insertion sort tem um desempenho aproximadamente linear. LEIC AED Inverno 2007/08 Algoritmos de ordenação 24

Bubble Sort Talvez o algoritmo mais utilizado e o que muitas pessoas aprendem primeiro Ideia: fazer múltiplas passagens pelos dados trocando de cada vez dois elementos adjacentes que estejam fora de ordem, até não haver mais trocas supostamente muito fácil de implementar usualmente mais lento que os dois métodos elementares estudados LEIC AED Inverno 2007/08 Algoritmos de ordenação 25

Implementação private static void bubblesort(int[] a, int l, int r) { for (int i = l; i < r; ++i) { for (int j = r; j > i; --j) { lessexch(a, j, j-1); } } } LEIC AED Inverno 2007/08 Algoritmos de ordenação 26

Bubble Sort - Comentários (1) Movendo da direita para a esquerda no ficheiro de dados quando o elemento mais pequeno é encontrado na primeira passagem é sucessivamente trocado com todos à sua esquerda acaba por ficar na primeira posição na segunda passagem o 2.º elemento mais pequeno é colocado na sua posição e por diante N passagens pelos dados são suficientes! É semelhante ao método de selecção tem mais trabalho para colocar cada elemento na sua posição final todas as trocas sucessivas até chegar à posição certa LEIC AED Inverno 2007/08 Algoritmos de ordenação 27

Bubble Sort - Comentários (2) Algoritmo pode ser melhorado, tal como o algoritmo de inserção código é muito semelhante mas não igual ciclo interno de Insertion Sort percorre a parte esquerda (ordenada) do array ciclo interno de Bubble Sort percorre a parte direita (não ordenada) do array no final de cada passagem podemos testar se houve mudanças se o array estiver ordenado, pára LEIC AED Inverno 2007/08 Algoritmos de ordenação 28

Bubble Sort -Análise Propriedade: Bubble sort usa aproximadamente N 2 /2 comparações e N 2 /2 trocas no pior caso; N 2 /4 trocas no caso médio Demonstração: A i-ésima passagem de Bubble Sort requer N-i operações de comparação/troca, logo a demonstração é semelhante a Selection sort Factos: Algoritmo pode depender criticamente dos dados se for modificado para terminar quando não houver mais trocas se o ficheiro estiver ordenado, apenas um passo é necessário se estiver em ordenação inversa então na i-ésima passagem são precisas N-i comparações e trocas caso médio é semelhante (análise mais complexa) LEIC AED Inverno 2007/08 Algoritmos de ordenação 29

Comparação dos algoritmos elementares de ordenação (1) Tempos de execução quadráticos Selection Insertion Bubble Comparações N 2 /2 N 2 /4 N 2 /2 Trocas N N 2 /4 N 2 /2 LEIC AED Inverno 2007/08 Algoritmos de ordenação 30

Comparação dos algoritmos elementares de ordenação (2) Ficheiros com elementos grandes e pequenas chaves Selection Sort é linear no número de dados N dados com tamanho M (palavras/words) considerando dados manipulados por valor tem-se: comparação -1 unidade; troca - M unidades N 2 /2 comparações e NM custo de trocas termo NM domina custo proporcional ao tempo necessário para mover os dados Ficheiros quase ordenados Insertion sort e Bubble sort são quase lineares os melhores algoritmos de ordenação podem ser quadráticos neste caso! LEIC AED Inverno 2007/08 Algoritmos de ordenação 31

Comparação dos algoritmos elementares de ordenação (3) int items Integer keys String keys N S I* I B S I B S I B 1000 14 54 8 54 100 55 130 129 65 170 2000 54 218 33 221 436 229 569 563 295 725 4000 212 848 129 871 1757 986 2314 2389 1328 3210 Legenda: S Selection sort I* Insertion sort, exchange-based I Insertion sort B Bubble sort LEIC AED Inverno 2007/08 Algoritmos de ordenação 32

Ordenação Síntese da Aula 2 Ordenação por inserção Insertion sort Versão elementar Versão adaptativa Exemplo de aplicação Análise de Eficiência Bubble sort Breve referência Descrição do algoritmo e análise funcionamento Exemplo de aplicação Análise de eficiência Comparação dos três primeiros algoritmos elementares Em número de comparações e trocas Na evolução da tabela durante a execução LEIC AED Inverno 2007/08 Algoritmos de ordenação 33

Shell sort (1) Shell sort (proposto por Donald Shell em 1959) é um algoritmo que requer no pior caso menos de O(n 2 ) comparações e trocas embora seja simples perceber intuitivamente o seu funcionamento, é extremamente difícil analisar o seu desempenho estimam-se desempenhos de ordem entre O(n 3/2 ) e O(n log 2 n) (melhor alcançado actualmente), dependendo dos detalhes de implementação Shell sort éuma generalização de Insertion sort que tem em conta duas observações: Insertion sort é eficiente se a entrada estiver ordenada ou quase ordenada Insertion sort é ineficiente, em média, porque apenas move os elementos de uma posição de cada vez LEIC AED Inverno 2007/08 Algoritmos de ordenação 34

Shell sort (2) Insertion sort: se o menor item está no final da tabela, serão precisos N passos para o colocar na posição correcta Shell sort: acelerar o algoritmo permitindo trocas entre elementos que estão afastados como? O Shell sort compara os elementos separados de uma distância (gap) de várias posições (p.ex. gap=5) são realizadas múltiplas passagens com passos sucessivamente menores, terminando com gap=1, que não é mais do que realizar Insertion sort mas nesta altura, os dados já estão praticamente ordenados Insertion sort éeficiente! LEIC AED Inverno 2007/08 Algoritmos de ordenação 35

Shell sort Exemplo (1) Suponha que se pretende ordenar o array 66, 95, 93, 82, 54, 40, 35, 19, 75, 24, 32, 43, 16, 68 Ordenar os elementos separados de uma distância h éo mesmo que particionar o array em linhas de h colunas e aplicar Insertion sort ao longo das colunas Execução de Shell sort com h=5: Sequência original h=5 Sequência ordenada por colunas usando Insertion sort 66 95 93 82 54 32 35 16 68 24 40 35 19 75 24 40 43 19 75 54 32 43 16 68 66 95 93 82 LEIC AED Inverno 2007/08 Algoritmos de ordenação 36

Shell sort Exemplo (2) Execução de Shell sort com h=3: Sequência original h=3 Sequência ordenada por colunas usando Insertion sort 32 35 16 32 19 16 68 24 40 43 24 40 43 19 75 54 35 75 54 66 95 68 66 95 93 82 93 82 LEIC AED Inverno 2007/08 Algoritmos de ordenação 37

Shell sort Exemplo (3) Execução de Shell sort com h=1 (Insertion sort): Sequência original (coluna única) h=1 32 19 16 43 24 40 54 35 75 68 66 95 93 82 Sequência ordenada usando Insertion sort 16 19 24 32 35 40 43 54 66 68 75 82 93 95 LEIC AED Inverno 2007/08 Algoritmos de ordenação 38

Shell sort Exemplo (4) Em termos de implementação, a ordenação das colunas com Insertion sort não é realizada sequencialmente, ordenar 1ª col., 2ª col., mas sim de forma entrelaçada como ilustrado neste exemplo. 66 40 32 Sequência original h=5 95 35 43 93 19 16 82 75 68 54 24 k= l+h+k k= l+h+k 0 1 2 3 4 40 66 35 95 19 93 75 82 24 54 32 43 16 68 5 6 7 8 32 35 16 68 24 40 43 19 75 54 66 95 93 82 LEIC AED Inverno 2007/08 Algoritmos de ordenação 39

Shell sort Implementação para o exemplo dado private static void shellsorttest(int[] a, int l, int r) { int incs[] = { 5, 3, 1 }; for (int k = 0; k < incs.length; ++k) { int h = incs[k]; // Insertion sort com passo (gap) h for (int i = l+h; i <= r; ++i) { int v = a[i], j = i; while (j >= l+h && less(v, a[j-h])) { a[j] = a[j-h]; j -= h; } a[j] = v; } } } LEIC AED Inverno 2007/08 Algoritmos de ordenação 40

Sequência de Ordenação (1) Difícil de escolher propriedades de muitas sequências foram já estudadas possível provar que umas são melhores que outras ex: 1, 4, 13, 40, 121, 364, 1093, 3280,... (Knuth, h=3*h ant +1) melhor que 1, 2, 4, 8, 16, 32, 64, 128, 256, 512,... (Shell, h=2 i ) -> O(n 2 ) Porquê? mas pior (20%) que 1, 8, 23, 77, 281, 1073, 4193, (Sedgewick, 4 i + 1 + 3(2 i ) + 1 ) na prática utilizam-se sequências que decrescem geometricamente para que o número de incrementos seja logarítmico LEIC AED Inverno 2007/08 Algoritmos de ordenação 41

Sequência de Ordenação (2) a sequência óptima não foi ainda descoberta (se é que existe) análise do algoritmo é desconhecida ninguém encontrou a fórmula que define a complexidade complexidade depende da sequência LEIC AED Inverno 2007/08 Algoritmos de ordenação 42

Shell sort Implementação genérica private static void shellsort(int[] a, int l, int r) { int h, length = r-l+1; for (h = 1; h < length; h = 3*h+1); // empty body for (h /= 3; h > 0; h /= 3) { // Insertion sort com passo (gap) h for (int i = l+h; i <= r; ++i) { int v = a[i], j = i; while (j >= l+h && less(v, a[j-h])) { a[j] = a[j-h]; j -= h; } a[j] = v; } } } LEIC AED Inverno 2007/08 Algoritmos de ordenação 43

Análise de Shell sort Propriedades: o resultado de h-ordenar um ficheiro que está k-ordenado é um ficheiro que está simultaneamente h- e k-ordenado Propriedade muito importante: indica a ordenação actual não estraga a ordenação realizada anteriormente Shell sort faz menos do que O(N 3/2 ) comparações para os incrementos (Knuth) 1, 4, 13, 40, 121, 364, 1093,... Shell sort faz menos do que O(N 4/3 ) comparações para os incrementos (Sedgewick) 1, 8, 23, 77, 281, 1073, 4193, 16577,... Nota: sequências até agora usam incrementos que são primos entre si Shell sort faz menos do que O(N lg 2 N) comparações para os incrementos (Pratt) 1, 2, 3, 4, 6, 8, 9, 12, 16,..., 2 p 3 q,... LEIC AED Inverno 2007/08 Algoritmos de ordenação 44

Vantagens de Shell sort rápido/eficiente pouco código melhor método para ficheiros pequenos e médios aceitável para elevados volumes de dados Muito utilizado na prática, embora difícil de compreender! LEIC AED Inverno 2007/08 Algoritmos de ordenação 45

Implementação genérica de algoritmos de ordenação (1) public class StaticGenericArraySort { private static boolean less(object x, Object y, Comparator cmp) { if (cmp == null) return ((Comparable)x).compareTo(y) < 0; else return cmp.compare(x, y) < 0; } private static void exch(object[] a, int i, int j) { Object aux = a[i]; a[i] = a[j]; a[j] = aux; } private static void lessexch(object[] a, int i, int j, Comparator cmp) { if (less(a[i], a[j], cmp)) exch (a, i, j); } private static void selectionsort(object[] a, int l, int r, Comparator cmp) { for (int i = l; i < r; ++i) { int min = i; for (int j = i+1; j <= r; ++j) if (less(a[j], a[min], cmp)) min = j; exch(a, i, min); } } LEIC AED Inverno 2007/08 Algoritmos de ordenação 46

Implementação genérica de algoritmos de ordenação (2) } // Métodos públicos public static void sort(object[] a, int l, int r, Comparator cmp) { selectionsort(a, l, r, cmp); } public static void main(string[] args) { Student[] students = {new Student("Nuno", 30), new Student("Luis", 10), new Student("Afonso", 40), new Student("Ana", 20) }; // Ordem natural, neste caso por nome de forma ascendente // (definido pelo método compareto) sort(students, 0, students.length-1, null); // ordenação por nome de forma descendente sort(students, 0, students.length-1, Student.BY_NAME); // ordenação por número de forma ascendente sort(students, 0, students.length-1, Student.BY_NUMBER); } LEIC AED Inverno 2007/08 Algoritmos de ordenação 47

Ordenar por diferentes critérios class Student implements Comparable<Student> { private String name; private int number; private static class ByName implements Comparator<Student> { public int compare(student a, Student b) { return -a.name.compareto(b.name); } // ordem inversa } private static class ByNumber implements Comparator<Student> { public int compare(student a, Student b) { return a.number - b.number; } } public static final Comparator<Student> BY_NAME = new ByName(); public static final Comparator<Student> BY_NUMBER = new ByNumber(); public int compareto(student s) { return this.name.compareto(s.name); } } LEIC AED Inverno 2007/08 Algoritmos de ordenação 48

Ordenação Síntese da Aula 3 Shell sort Apresentado como uma variante de aceleração do Insertion sort Descrição Implementação Sequências de ordenação Exemplo de aplicação Discussão da eficiência do algoritmo Condicionada pela sequência de ordenação utilizada Vantagens relativamente a outros algoritmos Implementação genérica de algoritmos de ordenação Ordenação por diferentes critérios LEIC AED Inverno 2007/08 Algoritmos de ordenação 49

Capítulo 2 - Algoritmos avançados de ordenação - Quicksort e Mergesort ISEL/LEIC - 2007/2008 2º ano, 1º Semestre * Estes acetatos foram parcialmente adaptados dos acetatos de AED da LEEC do Instituto Superior Técnico Prof. Rui Gustavo Crespo Nuno Leite AED: Algoritmos e Estruturas de Dados Semestre de Inverno 2007/08 http://www.deetc.isel.ipl.pt/programacao/aed/

Algoritmos avançados - Quicksort Provavelmente o algoritmo mais usado inventado em 1960 por Charles Hoare muito estudado e analisado desempenho bem conhecido popular devido à facilidade de implementação e eficiência complexidade N log 2 N, em média, para ordenar N objectos ciclo interno muito simples e conciso LEIC AED Inverno 2007/08 Algoritmos de ordenação 51

Quicksort Quicksort realiza 39% mais comparações do que o Mergesort Contudo, é mais rápido que o Mergesort na prática devido ao menor custo de outras instruções de alta frequência Mas: não é estável quadrático (N 2 ) no pior caso! frágil : qualquer pequeno erro de implementação pode não ser detectado mas levar a ineficiência LEIC AED Inverno 2007/08 Algoritmos de ordenação 52

Quicksort Algoritmo do tipo dividir para conquistar Algoritmo Quicksort: (Opcional): Baralhar (Shuffle) o array Particionar (Partition) o array da seguinte forma: elemento a[i] fica na sua posição final para um determinado i não existem elementos maiores do que a[i] à esquerda de i não existem elementos menores do que a[i] à direita de i Ordenar cada partição recorrentemente LEIC AED Inverno 2007/08 Algoritmos de ordenação 53

Quicksort -Partição LEIC AED Inverno 2007/08 Algoritmos de ordenação 54

Quicksort -Exemplo LEIC AED Inverno 2007/08 Algoritmos de ordenação 55

Estratégia para a partição Escolher a[r] para ser o elemento de partição o que é colocado na posição final Percorrer o array a partir da esquerda até encontrar um elemento maior que ou igual ao elemento de partição (a[r]) Percorrer o array a partir da direita até encontrar um elemento menor que ou igual ao elemento de partição (a[r]) estes dois elementos estão deslocados; trocamos as suas posições! Procedimento continua até nenhum elemento à esquerda de a[r] ser maior que ele, e nenhum elemento à direita de a[r] ser menor que ele termina quando os índices se cruzam completa-se trocando a[r] com o elemento referenciado pelo índice i (que varre da esquerda para a direita) LEIC AED Inverno 2007/08 Algoritmos de ordenação 56

Quicksort - Implementação public class IntArraySort { public static void quicksort(int[] a, int l, int r) { shuffle(a, l, r); // Opcional qsort(a, 0, a.length - 1); } private static void qsort(int[] a, int l, int r) { if (r <= l) return; int m = partition(a, l, r); qsort(a, l, m-1); qsort(a, m+1, r); } LEIC AED Inverno 2007/08 Algoritmos de ordenação 57

Quicksort - Implementação private static int partition(int[] a, int l, int r) { int i = l-1, j = r; int v = a[r]; for (;;) { // Encontra índice de elemento >= pivot à esquerda while (less(a[++i], v)) ; // Encontra índice elemento<=pivot à direita while (less(v, a[--j])) if (j == l) break; if (i >= j) break; exch(a, i, j); } exch(a, i, r); // Troca com pivot de partição return i; // Retorna índice do pivot } LEIC AED Inverno 2007/08 Algoritmos de ordenação 58

Quicksort -Partição Eficiência do processo de ordenação depende de quão bem a partição divide os dados depende por seu turno do elemento de partição será tanto mais equilibrada quanto mais perto este elemento estiver do meio da tabela na sua posição final Processo de partição não é estável qualquer chave pode ser movida para trás de várias outras chaves iguais a si (que ainda não foram examinadas) não é conhecida nenhuma forma simples de implementar uma versão estável de Quicksort baseada em arrays LEIC AED Inverno 2007/08 Algoritmos de ordenação 59

Quicksort Características de desempenho Se não se usar o shuffling, o Quicksort pode ser muito ineficiente em casos patológicos Propriedade: Quicksort usa cerca de N 2 /2 comparações no pior caso No pior caso, o número de comparações usadas por Quicksort satisfaz a recorrência de dividir para conquistar C(n) = C(n-1) + O(n) 1º termo cobre o custo de ordenar um sub-ficheiro (partição degenerada) 2º termo refere-se a examinar cada elemento C(n) = O(n 2 ) LEIC AED Inverno 2007/08 Algoritmos de ordenação 60

Quicksort Análise do pior caso Se o ficheiro já estiver ordenado, todas as partições degeneram e o programa chama-se a si próprio N vezes; o número de comparações é de N + (N-1) + (N-2) + + 2 + 1 = (N + 1)N / 2 (mesma situação se o ficheiro estiver ordenado por ordem inversa) Não apenas o tempo necessário para a execução do algoritmo cresce quadraticamente como o espaço necessário para o processo recorrente é de cerca de N o que é inaceitável para ficheiros grandes LEIC AED Inverno 2007/08 Algoritmos de ordenação 61

Quicksort Características de desempenho Melhor caso: quando cada partição divide o ficheiro de entrada exactamente em metade número de comparações usadas por Quicksort satisfaz a recorrência de dividir para conquistar C(n) = 2C(n/2) + O(n) 1º termo cobre o custo de ordenar os dois sub-ficheiros 2º termo refere-se a examinar cada elemento solução é C(n) = O(n log 2 n) (vimos numa aula anterior) Espaço usado nas chamadas recorrentes é log 2 (n) Demonstração... LEIC AED Inverno 2007/08 Algoritmos de ordenação 62

Quicksort Características de desempenho Propriedade: Quicksort usa cerca de O(2N log 2 N) comparações em média Demonstração: A fórmula de recorrência exacta para o número de comparações utilizado por Quicksort para ordenar N números distintos aleatoriamente posicionados é C(n) = n + 1 + 1 n n k= 1 (C(k 1) + C(n k)) n 2,C(0) = C(1) = termo n+1 cobre o custo de comparar o elemento de partição com os restantes (2 comparações extra: ponteiros cruzam-se) resto vem do facto de que cada elemento tem probabilidade 1/n de ser o elemento de partição após o que ficamos com dois sub-arrays de tamanhos k-1 e n-k 0 LEIC AED Inverno 2007/08 Algoritmos de ordenação 63

Quicksort Características de desempenho Demonstração (cont.) C(n) = n + 1 + 1 n n k= 1 (C(k 1) + C(n k)) = n + 1 + 2 n n k= 1 C(k 1) Multiplicar ambos os lados da equação por n e subtrair a mesma fórmula por n-1 nc(n) -(n -1)C(n -1) = n(n + 1) -(n -1)n + Simplificar para: 2C(n -1) nc(n) = (n + 1)C(n 1) + 2n LEIC AED Inverno 2007/08 Algoritmos de ordenação 64

Quicksort Características de desempenho Dividir ambos os lados da equação por n(n-1) de forma a obter a soma: C(n) = n + 1 = = = = C(n -1) 2 + n n + 1 C(n - 2) 2 2 + + n -1 n n + 1 C(n - 3) 2 2 + + + n - 2 n -1 n M C(2) 3 + n k= 3 2 k+ 1 2 n + 1 Aproximar a resposta exacta por um integral: C(n) = n + 1 k= 1 2 n 2 = n k k= 1 k 2ln Finalmente, obtém-se a solução: n C(n) = 2(n + 1) ln n 1.39n log2 n. LEIC AED Inverno 2007/08 Algoritmos de ordenação 65

Quicksort Características de desempenho Análise assume que os dados estão aleatoriamente ordenados e têm chaves diferentes pode ser lento em situações em que as chaves não são distintas ou que os dados não estão aleatoriamente ordenados (como vimos) Algoritmo pode ser melhorado para reduzir a probabilidade que estes casos sucedam! necessário em ficheiros de grandes dimensões ou se o algoritmo for usado como função genérica numa biblioteca LEIC AED Inverno 2007/08 Algoritmos de ordenação 66

Ordenação Síntese da Aula 4 Algoritmo Quicksort Ideia chave + Motivação Algoritmo que recorre à divisão em instâncias menores divide and conquer Código Exemplo de aplicação Descrição detalhada do mecanismo de partição Análise de eficiência Pior caso Melhor caso Caso médio LEIC AED Inverno 2007/08 Algoritmos de ordenação 67

Quicksort Questões mais relevantes Possível redução de desempenho devido ao uso de recorrência Tempo de execução dependente dos dados de entrada Tempo de execução quadrático no pior caso um problema Espaço/memória necessário no pior caso é linear um problema sério (para ficheiros de grandes dimensões) Problema do espaço está associado ao uso de recorrência: recorrência implica chamada a função e logo a carregar dados na pilha/stack do computador no pior caso todas as partições degeneram e há O(N) níveis de recorrência (em vez de O(log 2 (N)) no melhor caso) pilha cresce até ordem N LEIC AED Inverno 2007/08 Algoritmos de ordenação 68

Quicksort - Espaço necessário (1) Para resolver este problema usamos uma pilha (stack) explícita pilha contém trabalho a ser processado, na forma de sub-arrays a ordenar quando precisamos de um sub-array para processar tiramo-lo da pilha (i.e. fazemos um pop() do stack) por cada partição criamos dois sub-arrays e metemos ambos na pilha (i.e. fazemos dois push() para o stack) substitui a pilha do computador que é usada na implementação recorrente LEIC AED Inverno 2007/08 Algoritmos de ordenação 69

Quicksort - Espaço necessário (2) Conduz a uma versão não recorrente de Quicksort verifica os tamanhos dos dois subarrays e põe o maior deles primeiro na pilha (e o menor depois; logo o menor é retirado e tratado primeiro) ordem de processamento dos subarrays não afecta a correcta operação da função ou o tempo de processamento mas afecta o tamanho da pilha No pior caso espaço extra para a ordenação é logarítmico em N garante que dimensão máxima do stack é O(log 2 N) LEIC AED Inverno 2007/08 Algoritmos de ordenação 70

Quicksort - Versão não-recursiva (1) static void nonrecursivequicksort(int[] a, int l, int r) { shuffle(a, l, r); // Shuffle IntStack s = new IntStackArray(50); s.push(l); s.push(r); while (!s.isempty()) { r = s.pop(); l = s.pop(); if (r <= l) continue; int i = partition(a, l, r); if (i-l > r-i) { s.push(l); s.push(i-1); } s.push(i+1); s.push(r); if (r-i >= i-l) { s.push(l); s.push(i-1); } } } LEIC AED Inverno 2007/08 Algoritmos de ordenação 71

Quicksort - Versão não-recursiva (2) Política de colocar o maior dos subarrays primeiro na pilha garante que cada entrada na pilha não é maior do que metade da que estiver antes dela na pilha pilha apenas ocupa log 2 N no pior caso que ocorre agora quando a partição ocorre sempre no meio da tabela em ficheiros aleatórios o tamanho máximo da pilha é bastante menor Propriedade: se o menor dos dois subarrays é ordenado primeiro a pilha nunca necessita mais do que log 2 N entradas quando Quicksort é usado para ordenar N elementos LEIC AED Inverno 2007/08 Algoritmos de ordenação 72

Quicksort - Versão não-recursiva (3) Demonstração: no pior caso o tamanho da pilha é inferior a T(n) em que T(n) satisfaz a recorrência T(n) = T n/2 = + 1 com T(0) = T(1) 0 que foi já estudada anteriormente LEIC AED Inverno 2007/08 Algoritmos de ordenação 73

Quicksort - Melhoramentos (1) Algoritmo pode ainda ser melhorado com alterações triviais porquê colocar ambos os subarrays na pilha se um deles é de imediato retirado? Teste para r <= l é feito assim que os subarrays saem da pilha seria melhor nunca os lá ter colocado! ordenação de ficheiros/subarrays de pequenas dimensões pode ser efectuada de forma mais eficiente como escolher correctamente o elemento de partição? Como melhorar o desempenho se os dados tiverem um grande número de chaves repetidas? LEIC AED Inverno 2007/08 Algoritmos de ordenação 74

Quicksort - Melhoramentos (2) Pequenos ficheiros/sub-arrays Até mesmo o QuickSort apresenta um overhead excessivo quando é usado com ficheiros de pequena dimensão conveniente utilizar o melhor método possível quando encontra tais ficheiros forma óbvia de obter este comportamento é mudar o teste no início da função recorrente para uma chamada a Insertion sort if (r-l <= M) insertionsort(a, l, r) em que M é um parâmetro a definir na implementação LEIC AED Inverno 2007/08 Algoritmos de ordenação 75

Quicksort - Melhoramentos (3) Pequenos ficheiros/subarrays outra solução é a de simplesmente ignorar ficheiros pequenos (tamanho menor que M) durante a partição: if (r-l <= M) return; neste caso no final teremos um ficheiro que está praticamente todo ordenado Boa solução neste caso é usar insertion sort algoritmo híbrido: bom método em geral! LEIC AED Inverno 2007/08 Algoritmos de ordenação 76

Quicksort - Melhoramentos (4) 1º Método: Utilizar um elemento de partição que com alta probabilidade divida o ficheiro pela metade pode usar-se um elemento aleatoriamente escolhido evita o pior caso (i.e. pior caso tem baixa probabilidade de acontecer) é um exemplo de um algoritmo probabilístico um que usa aleatoriedade para obter bom desempenho com alta probabilidade independentemente dos dados de entrada pode ser demasiado pesado incluir gerador aleatório no algoritmo; existem outros métodos igualmente simples LEIC AED Inverno 2007/08 Algoritmos de ordenação 77

Quicksort - Melhoramentos (5) 2º Método: pode escolher-se alguns (ex: três) elementos do ficheiro e usar a mediana dos três como elemento de partição escolhendo os três elementos da esquerda, meio e direita da tabela podemos incorporar sentinelas na ordenação ordenamos os três elementos, depois trocamos o do meio com a[r-1] e executamos o algoritmo de partição em a[l+1] a[r-1] Este melhoramento chama-se o método da mediana de três median - of - three LEIC AED Inverno 2007/08 Algoritmos de ordenação 78

Mediana de três - Implementação private final static int M = 10; static void quicksort(int[] a, int l, int r) { if (r-l <= M) return; exch(a, (l+r)/2, r-1); lessexch(a, r-1, l); lessexch(a, r, l); lessexch(a, r, r-1); int i = partition(a, l+1, r-1); quicksort(a, l, i-1); quicksort(a, i+1, r); } static void hybridsort(int a[], int l, int r) { quicksort(a, l, r); insertionsort(a, l, r); } LEIC AED Inverno 2007/08 Algoritmos de ordenação 79

Quicksort - Melhoramentos (6) Método da mediana de três melhora Quicksort por duas razões o pior caso é mais improvável de acontecer na prática dois dos três elementos teriam de ser dos maiores ou menores do ficheiro e isto teria de acontecer constantemente a todos os níveis de partição reduz o tempo médio de execução do algoritmo embora apenas por cerca de 5% junto com o método de tratar de pequenos ficheiros pode resultar em ganhos de 20 a 25% É possível pensar em outros melhoramentos mas o acréscimo de eficiência é marginal (ex: porque não fazer a mediana de cinco?) LEIC AED Inverno 2007/08 Algoritmos de ordenação 80

Quicksort - Chaves duplicadas (1) Ficheiros com um grande número de chaves duplicadas são frequentes na prática ex: ordenar população por idade; remover duplicados de uma lista desempenho de Quicksort pode ser substancialmente melhorado se todas as chaves forem iguais Quicksort mesmo assim faz O(N log 2 N) comparações LEIC AED Inverno 2007/08 Algoritmos de ordenação 81

Quicksort - Chaves duplicadas (2) Uma possibilidade é dividir o ficheiro em três partes cada uma para chaves menores, iguais e maiores que o elemento de partição não é trivial de implementar, sobretudo se se impuser que a ordenação deverá ser feita com apenas uma passagem pelos dados Solução simples para este problema é fazer uma partição em três partes manter chaves iguais ao elemento de partição que são encontradas no sub-ficheiro da esquerda do lado esquerdo do ficheiro manter chaves iguais ao elemento de partição que são encontradas no sub-ficheiro da direita do lado direito do ficheiro LEIC AED Inverno 2007/08 Algoritmos de ordenação 82

Quicksort - Chaves duplicadas (3) Quando os ponteiros/índices de pesquisa se cruzam sabemos onde estão os elementos iguais ao de partição e é fácil colocá-los em posição não faz exactamente tudo num só passo mas quase... trabalho extra para chaves duplicadas é proporcional ao número de chaves duplicadas: funciona bem se não houver chaves duplicadas linear quando há um número constante de chaves!! LEIC AED Inverno 2007/08 Algoritmos de ordenação 83

Quicksort - Partição em três static void quicksort(int a[], int l, int r) { if (r <= l) return; int v = a[r], i = l, j = r-1, p = l-1, q = r, k; for (;;) { while (less(a[i], v)) ++i; while (j >= l && less(v, a[j])) ++j; if (i >= j) break; exch(a, i, j); if (equal(a[i], v)) { p++; exch(a, p, i); } if (equal(v, a[j])) { q--; exch(a, q, j); } } exch(a, i, r); j = i-1; i = i+1; for (k = l ; k <= p; k++,j--) exch(a, k, j); for (k = r-1; k >= q; k--,i++) exch(a, k, i); quicksort(a, l, j); quicksort(a, i, r); } LEIC AED Inverno 2007/08 Algoritmos de ordenação 84

Junção versus partição Quicksort é baseado na operação de selecção do elemento de partição (pivot) a partição divide um ficheiro em duas partes quando as duas metades do ficheiro estão ordenadas, o ficheiro está ordenado Operação complementar é de junção (merge) dividir o ficheiro em duas partes para serem ordenados e depois combinar as partes de forma a que o ficheiro total fique ordenado Mergesort Mergesort tem uma propriedade muito interessante: ordenação de um ficheiro de N elementos é feito em tempo proporcional a N log N, independentemente dos dados! Outros algoritmos, p.ex. HeapSort, também têm desempenho desta ordem LEIC AED Inverno 2007/08 Algoritmos de ordenação 85

Ordenação Síntese da Aula 5 Análise do algoritmo Quicksort Discussão relativa à memória utilizada na versão recorrente Alternativa de implementação por pilha e suas vantagens na perspectiva da memória utilizada Código para Quicksort em versão não recorrente Melhoramentos na versão não recorrente Mecanismos de partição alternativos Aleatórios Mediana de três Estratégia de melhoramento em presença de chaves duplicadas Ideia base Código LEIC AED Inverno 2007/08 Algoritmos de ordenação 86