Professional Documents
Culture Documents
DCOMP/UFSJ
AEDSII
Ordenacao
DCOMP/UFSJ
AEDSII
Ordenacao
Qualquer tipo de chave sobre o qual exista uma regra de ordenao bemdenida pode ser utilizado Um mtodo de ordenao estvel se a ordem relativa dos itens com chaves iguais no se altera durante a ordenao Alguns dos mtodos de ordenao mais ecientes no so estveis A estabilidade pode ser forada quando o mtodo no-estvel
DCOMP/UFSJ AEDSII
Ordenacao
Sedgewick (1988) sugere agregar um pequeno ndice a cada chave antes de ordenar, ou ento aumentar a chave de alguma outra forma
DCOMP/UFSJ
AEDSII
Ordenacao
DCOMP/UFSJ
AEDSII
Ordenacao
DCOMP/UFSJ
AEDSII
Ordenacao
DCOMP/UFSJ
AEDSII
Ordenacao
Ordenao Interna
Na escolha de um algoritmo de ordenao interna deve ser considerado o tempo gasto pela ordenao Sendo n o nmero registros no arquivo, as medidas de complexidade relevantes so: Nmero de comparaes C(n) entre chaves Nmero de movimentaes M (n) de itens do arquivo O uso econmico da memria disponvel um requisito primordial na ordenao interna Mtodos de ordenao in situ so os preferidos Mtodos que utilizam listas encadeadas no so muito utilizados Mtodos que fazem cpias dos itens a serem ordenados possuem menor importncia
DCOMP/UFSJ AEDSII
Ordenacao
Ordenao Interna
Classicao dos mtodos de ordenao interna: Mtodos simples: Adequados para pequenos arquivos Requerem O(n2) comparaes Produzem programas pequenos Mtodos ecientes: Adequados para arquivos maiores Requerem O(n log n) comparaes Usam menos comparaes As comparaes so mais complexas nos detalhes Mtodos simples so mais ecientes para pequenos arquivos
DCOMP/UFSJ
AEDSII
Ordenacao
Ordenao Interna
Tipos de dados e variveis utilizados nos algoritmos de ordenao interna: typedef int Indice; typedef Item Vetor[MAX_TAM + 1]; Vetor A;
O ndice do vetor vai de 0 at M AX T AM + 1, devido s chaves sentinelas O vetor a ser ordenado contm chaves nas posies de 1 at n
DCOMP/UFSJ
AEDSII
Ordenacao
10
DCOMP/UFSJ
AEDSII
Ordenacao
11
DCOMP/UFSJ
AEDSII
Ordenacao
12
DCOMP/UFSJ
AEDSII
Ordenacao
13
DCOMP/UFSJ
AEDSII
Ordenacao
14
DCOMP/UFSJ
AEDSII
Ordenacao
15
DCOMP/UFSJ
AEDSII
Ordenacao
16
DCOMP/UFSJ
AEDSII
Ordenacao
17
Assumindo que todas as permutaes de n so igualmente provveis no caso mdio, temos: melhor caso: C(n) = (1 + 1 + . . . + 1) = n 1 2 pior caso: C(n) = (2 + 3 + . . . + n) = n + n 1 2 2
1 (3 + 4 + . . . + n + 1) = n2 + 3n 1 caso mdio: C(n) = 2 4 4
DCOMP/UFSJ
AEDSII
Ordenacao
18
DCOMP/UFSJ
AEDSII
Ordenacao
19
DCOMP/UFSJ
AEDSII
Ordenacao
20
Shellsort
Proposto por Shell em 1959 uma extenso do algoritmo de ordenao por insero. Problema com o algoritmo de ordenao por insero: Troca a posio itens adjacentes para determinar o ponto de insero So efetuadas n 1 comparaes e movimentaes quando o menor item est na posio mais direita no vetor O mtodo de Shell contorna este problema permitindo trocas de registros distantes um do outro
DCOMP/UFSJ
AEDSII
Ordenacao
21
Shellsort
Os itens separados de h posies so rearranjados Todo h-simo item leva a uma seqncia ordenada Tal sequncia dita estar h-ordenada Exemplo de utilizao:
Ordenacao
22
Shellsort
Como escolher o valor de h Sequncia para h: h(s) = 3h(s 1) + 1 para s > 1 h(s) = 1, para s = 1 Knuth (1973) mostrou experimentalmente que esta seqncia difcil de ser batida por mais de 20% em ecincia A seqncia para h corresponde a 1, 4, 13, 40, 121, 364, 1.093, 3.280, . . .
DCOMP/UFSJ
AEDSII
Ordenacao
23
Shellsort
void shellsort(Vetor a, Indice *n);
DCOMP/UFSJ
AEDSII
Ordenacao
24
Shellsort
void shellsort(Vetor a, Indice *n) { int i, j; int h = 1; Item x; do h = h * 3 + 1; while (h < *n); do { h /= 3; for (i = h + 1; i <= *n; i++) { x = a[i]; j = i; while (a[j - h].chave > x.chave) { a[j] = a[j - h]; j -= h; if (j <= h) break; } a[j] = x; } } while (h != 1); }
DCOMP/UFSJ AEDSII
Ordenacao
25
Shellsort
A implementao do Shellsort no utiliza registros sentinelas Seriam necessrios h registros sentinelas, uma para cada h-ordenao
DCOMP/UFSJ
AEDSII
Ordenacao
26
Shellsort
A razo da ecincia do algoritmo ainda no conhecida Ningum ainda foi capaz de analisar o algoritmo A sua anlise contm alguns problemas matemticos muito difceis, a comear pela prpria sequncia de incrementos O que se sabe que cada incremento no deve ser mltiplo do anterior Conjecturas referente ao nmero de comparaes para a seqncia de Knuth: Conjectura 1: C(n) = O(n1,25) Conjectura 2: C(n) = O(n(ln n)2)
DCOMP/UFSJ
AEDSII
Ordenacao
27
Shellsort
Vantagens: Shellsort uma tima opo para arquivos de tamanho moderado Sua implementao simples e requer uma quantidade de cdigo pequena Desvantagens: O tempo de execuo do algoritmo sensvel ordem inicial do arquivo O mtodo no estvel
DCOMP/UFSJ
AEDSII
Ordenacao
28
Quicksort
Proposto por Hoare em 1960 e publicado em 1962 o algoritmo de ordenao interna mais rpido que se conhece para uma ampla variedade de situaes Provavelmente o mais utilizado A idia bsica dividir o problema de ordenar um conjunto com n itens em dois problemas menores Os problemas menores so ordenados independentemente Os resultados so combinados para produzir a soluo nal
DCOMP/UFSJ
AEDSII
Ordenacao
29
Quicksort
A parte mais delicada do mtodo o processo de partio O vetor A[Esq..Dir] rearranjado por meio da escolha arbitrria de um piv x O vetor A particionado em duas partes: A parte esquerda com chaves menores ou iguais a x A parte direita com chaves maiores ou iguais a x
DCOMP/UFSJ
AEDSII
Ordenacao
30
Quicksort
Algoritmo para o particionamento: 1. Escolha arbitrariamente um piv x 2. Percorra o vetor a partir da esquerda at que A[i] x 3. Percorra o vetor a partir da direita at que A[j] x 4. Troque A[i] com A[j] 5. Continue este processo at os apontadores i e j se cruzarem Ao nal, o vetor A[Esq..Dir] est particionado de tal forma que: Os itens em A[esq], A[esq + 1], . . . , A[j] so menores ou iguais a x Os itens em A[i], A[i + 1], . . . , A[dir] so maiores ou iguais a x
DCOMP/UFSJ
AEDSII
Ordenacao
31
Quicksort
Ilustrao do processo de partio:
O piv x escolhido como sendo A[(i + j)div2] Como inicialmente i = 1 e j = 6, ento x = A[3] = D Ao nal do processo de partio, i e j se cruzam em i = 3 e j = 2
DCOMP/UFSJ AEDSII
Ordenacao
32
Quicksort
void particionar(Indice esq, Indice dir, Indice *i, Indice *j, Vetor a) { Item x, w; *i = esq; *j = dir; x = a[(*i + *j) / 2]; /* obtem o pivo x */ do { while (x.chave > a[*i].chave) (*i)++; while (x.chave < a[*j].chave) (*j)--; if (*i <= *j) { w = a[*i]; a[*i] = a[*j]; a[*j] = w; (*i)++; (*j)--; } } while (*i <= *j); }
DCOMP/UFSJ
AEDSII
Ordenacao
33
Quicksort
O anel interno do procedimento particionar extremamente simples (razo pela qual o algoritmo Quicksort to rpido)
DCOMP/UFSJ
AEDSII
Ordenacao
34
Procedimento Quicksort
void ordenar(Indice esq, Indice dir, Vetor a) { Indice i, j; particionar(esq, dir, &i, &j, a); if (esq < j) ordenar(esq, j, a); if (i < dir) ordenar(i, dir, a); } void quicksort(Vetor a, Indice *n) { ordenar(1, *n, a); }
DCOMP/UFSJ
AEDSII
Ordenacao
35
Procedimento Quicksort
Exemplo do estado do vetor em cada chamada recursiva do procedimento Ordena:
DCOMP/UFSJ
AEDSII
Ordenacao
36
Quicksort - Anlise
Seja C(n) a funo que conta o nmero de comparaes Pior caso: C(n) = O(n2) Ocorre quando o piv escolhido sempre como sendo um dos extremos de um arquivo j ordenado Isto faz com que o procedimento ordenar seja chamado recursivamente n vezes, eliminando apenas um item em cada chamada O pior caso pode ser evitado empregando pequenas modicaes no algoritmo Basta escolher trs itens quaisquer do vetor e usar a mediana dos trs como piv
DCOMP/UFSJ
AEDSII
Ordenacao
37
Quicksort - Anlise
Melhor caso: C(n) = 2C(n/2) + n = n log n n + 1 Ocorre quando cada partio divide o arquivo em duas partes iguais Caso mdio de acordo com Sedgewick e Flajolet (1996) C(n) 1, 386n log n 0, 846n Isso signica que, em mdia, o tempo de execuo do Quicksort O(n log n)
DCOMP/UFSJ
AEDSII
Ordenacao
38
Quicksort
Vantagens: extremamente eciente para ordenar arquivos de dados Necessita de apenas uma pequena pilha como memria auxiliar Requer cerca de n log n comparaes em mdia para ordenar n itens Desvantagens: Pior caso: O(n2) comparaes Implementao muito delicada e difcil:Um pequeno engano pode levar a efeitos inesperados para algumas entradas de dados No estvel
DCOMP/UFSJ
AEDSII
Ordenacao
39
Heapsort
Possui o mesmo princpio de funcionamento da ordenao por seleo Algoritmo: 1. Selecione o menor item do vetor 2. Troque-o com o item da primeira posio do vetor 3. Repita estas operaes com os n 1 itens restantes, depois com os n 2 itens, e assim sucessivamente O custo para encontrar o menor (ou o maior) item entre n itens n 1 comparaes Isso pode ser reduzido utilizando uma la de prioridades
DCOMP/UFSJ
AEDSII
Ordenacao
40
DCOMP/UFSJ
AEDSII
Ordenacao
41
DCOMP/UFSJ
AEDSII
Ordenacao
42
DCOMP/UFSJ
AEDSII
Ordenacao
43
DCOMP/UFSJ
AEDSII
Ordenacao
44
Ordenacao
45
Heapsort - Heaps
uma seqncia de itens com chaves c[1], c[2], . . . , c[n], tal que: c[i] c[2i], c[i] c[2i + 1], para todo i = 1, 2, . . . , n/2 A denio pode ser facilmente visualizada em uma rvore binria completa:
Ordenacao
46
DCOMP/UFSJ
AEDSII
Ordenacao
47
Heapsort - Heaps
As chaves na rvore satisfazem a condio do heap A chave em cada n maior do que as chaves em seus lhos A chave no n raiz a maior chave do conjunto Uma rvore binria completa pode ser representada por um array:
A representao extremamente compacta Permite caminhar pelos ns da rvore facilmente Os lhos de um n i esto nas posies 2i e 2i + 1 O pai de um n i est na posio i div 2
DCOMP/UFSJ AEDSII
Ordenacao
48
Heapsort - Heaps
Na representao do heap em um arranjo, a maior chave est sempre na posio 1 do vetor Os algoritmos para implementar as operaes sobre o heap operam ao longo de um dos caminhos da rvore Um algoritmo elegante para construir o heap foi proposto por Floyd em 1964 O algoritmo no necessita de nenhuma memria auxiliar Dado um vetor A[1], A[2], . . . , A[n], os itens A[n/2 + 1], A[n/2 + 2], . . . , A[n] formam um heap: Neste intervalo no existem dois ndices i e j tais que j = 2i ou j = 2i+1
DCOMP/UFSJ
AEDSII
Ordenacao
49
Heapsort - Heaps
Algoritmo:
Os itens de A[4] a A[7] formam um heap O heap estendido para a esquerda (Esq = 3), englobando o item A[3], pai dos itens A[6] e A[7] A condio de heap violada:
DCOMP/UFSJ AEDSII
Ordenacao
50
O heap refeito trocando os itens D e S O item R incluindo no heap (esq = 2), o que no viola a condio de heap O item O incluindo no heap (esq = 1) A Condio de heap violada: O heap refeito trocando os itens O e S, encerrando o processo
DCOMP/UFSJ
AEDSII
Ordenacao
51
Heapsort - Heaps
void refazer(Indice esq, Indice dir, Vetor a) { Indice i = esq; int j; Item x; j = i * 2; x = a[i]; while (j <= dir) { if (j < dir) { if (a[j].chave < a[j+1].chave) j++; } if (x.chave >= a[j].chave) break; a[i] = a[j]; i = j; j = i * 2; } a[i] = x; }
DCOMP/UFSJ AEDSII
Ordenacao
52
Heapsort - Heaps
void construir(Vetor a, Indice *n) { Indice esq; esq = *n / 2 + 1; while (esq > 1) { esq--; refazer(esq, *n, a); } }
DCOMP/UFSJ
AEDSII
Ordenacao
53
Heapsort - Algoritmo
1. Construir o heap 2. Trocar o item na posio 1 do vetor (raiz do heap) com o item da posio n 3. Use o procedimento refazer para reconstituir o heap para os itens A[1], A[2], . . . , A[n 1] 4. Repita os passos 2 e 3 com os n 1 itens restantes, depois com os n 2, at que reste apenas um item
DCOMP/UFSJ
AEDSII
Ordenacao
54
Heapsort - Exemplo
O caminho seguido pelo procedimento refazer para reconstituir a condio do heap est em negrito Por exemplo, aps a troca dos itens S e D na segunda linha da Figura, o item D volta para a posio 5, aps passar pelas posies 1 e 2
DCOMP/UFSJ AEDSII
Ordenacao
55
Heapsort - Algoritmo
void heapsort(Vetor a, Indice *n) { Indice esq, dir; Item x; construir(a, n); /* constroi o heap */ esq = 1; dir = *n; while (dir > 1) { /* ordena o vetor */ x = a[1]; a[1] = a[dir]; a[dir] = x; dir--; refazer(esq, dir, a); } }
DCOMP/UFSJ
AEDSII
Ordenacao
56
Heapsort - Anlise
O procedimento refazer gasta cerca de log n operaes, no pior caso Logo, Heapsort gasta um tempo de execuo proporcional a n log n, no pior caso
DCOMP/UFSJ
AEDSII
Ordenacao
57
Heapsort
Vantagem: O comportamento do Heapsort sempre O(n log n), qualquer que seja a entrada. Desvantagens: O anel interno do algoritmo bastante complexo se comparado com o do Quicksort No estvel Recomendado: Para aplicaes que no podem tolerar eventualmente um caso desfavorvel No recomendado para arquivos com poucos registros, por causa do tempo necessrio para construir o heap
DCOMP/UFSJ AEDSII
Ordenacao
58
DCOMP/UFSJ
AEDSII
Ordenacao
59
DCOMP/UFSJ
AEDSII
Ordenacao
60
DCOMP/UFSJ
AEDSII
Ordenacao
61
DCOMP/UFSJ
AEDSII
Ordenacao
62
Ordenacao
63
O Insero o mais rpido para qualquer tamanho se os elementos esto ordenados O Insero o mais lento para qualquer tamanho se os elementos esto em ordem descendente Entre os algoritmos de custo O(n2), o Insero melhor para todos os tamanhos aleatrios experimentados
DCOMP/UFSJ
AEDSII
Ordenacao
64
DCOMP/UFSJ
AEDSII
Ordenacao
65
DCOMP/UFSJ
AEDSII
Ordenacao
66
DCOMP/UFSJ
AEDSII
Ordenacao
67
Ordenacao
68
O pior caso tem uma probabilidade muito remota de ocorrer quando os elementos forem aleatrios
DCOMP/UFSJ
AEDSII
Ordenacao
69
DCOMP/UFSJ
AEDSII
Ordenacao
70
DCOMP/UFSJ
AEDSII
Ordenacao
71
Seja P um arranjo P [1], P [2], . . . , P [n] de apontadores Os registros somente so acessados para ns de comparaes e toda movimentao realizada sobre os apontadores Ao nal, P [1] contm o ndice do menor elemento de A, P [2] o ndice do segundo menor e assim sucessivamente
DCOMP/UFSJ AEDSII
Ordenacao
72
Essa estratgia pode ser utilizada para qualquer dos mtodos de ordenao interna
DCOMP/UFSJ
AEDSII
Ordenacao
73
Mergesort
Mtodo particular Aplica a tcnica de Projeto de Algoritmos (AEDSIII) "Dividir para Conquistar" Divide o vetor em 2 sub-vetores de comprimento n/2 e n/2 Ordena recursivamente cada sub-vetor Intercala os sub-vetores (merge)
DCOMP/UFSJ
AEDSII
Ordenacao
74
Mergesort - Exemplo
DCOMP/UFSJ
AEDSII
Ordenacao
75
Mergesort - Merge
Normalmente, precisa de um vetor auxiliar para manter a ordenao dos subvetores (ou seja, no in situ) (mas possivel implementar com apenas um vetor)
DCOMP/UFSJ
AEDSII
Ordenacao
76
Mergesort
void mergeSort(int vec[], int vecSize) { int mid; if (vecSize > 1) { mid = vecSize / 2; mergeSort(vec, mid); mergeSort(vec + mid, vecSize - mid); merge(vec, vecSize); } }
DCOMP/UFSJ
AEDSII
Ordenacao
77
Mergesort - Merge
void merge(int vec[], int vecSize) { int mid; int i, j, k; int* tmp; tmp = (int*) malloc(vecSize * sizeof(int)); if (tmp == NULL) { exit(1); } mid = vecSize / 2; i = 0; j = mid; k = 0; while (i < mid && j < vecSize) { if (vec[i] < vec[j]) { tmp[k] = vec[i]; ++i; } else { tmp[k] = vec[j]; ++j; } ++k; } if (i == mid) { while (j < vecSize) {tmp[k] = vec[j]; ++j; ++k; } } else { while (i < mid) {tmp[k] = vec[i]; ++i; ++k;} for (i = 0; i < vecSize; ++i) {vec[i] = tmp[i];} free(tmp); }
DCOMP/UFSJ AEDSII
Ordenacao
78
Mergesort
Complexidade: O(n log n) Vantagens: complexidade constante; implementao simples Desvantagem: Alto uso de memria (pela necessidade de copiar o vetor e pelas chamadas recursivas) Uso: necessidade de complexidade constante; memria no problema
DCOMP/UFSJ
AEDSII
Ordenacao
79
Ordenao Externa
Consiste em ordenar arquivos de tamanho maior que a memria interna disponvel Mtodos muito diferentes dos de ordenao interna Algoritmos devem diminuir o nmero de acesso as unidades de memria externa Nas memrias externas, os dados so armazenados como um arquivo seqencial Apenas um registro pode ser acessado em um dado momento Esta uma restrio forte se comparada com as possibilidades de acesso em um vetor
DCOMP/UFSJ AEDSII
Ordenacao
80
Logo, os mtodos de ordenao interna so inadequados para ordenao externa Tcnicas de ordenao completamente diferentes devem ser utilizadas
DCOMP/UFSJ
AEDSII
Ordenacao
81
Ordenao Externa
Fatores que determinam as diferenas das tcnicas de ordenao externa: Custo para acessar um item algumas ordens de grandeza maior O custo principal na ordenao externa relacionado a transferncia de dados entre a memria interna e externa Existem restries severas de acesso aos dados O desenvolvimento de mtodos de ordenao externa muito dependente do estado atual da tecnologia A variedade de tipos de unidades de memria externa torna os mtodos dependentes de vrios parmetros Assim, apenas mtodos gerais sero apresentados
DCOMP/UFSJ
AEDSII
Ordenacao
82
Ordenao Externa
O mtodo mais importante o de ordenao por intercalao Intercalar signica combinar dois ou mais blocos ordenados em um nico bloco ordenado A intercalao utilizada como uma operao auxiliar na ordenao Estratgia geral dos mtodos de ordenao externa: Quebre o arquivo em blocos do tamanho da memria interna disponvel Ordene cada bloco na memria interna Intercale os blocos ordenados, fazendo vrias passadas sobre o arquivo A cada passada so criados blocos ordenados cada vez maiores, at que todo o arquivo esteja ordenado
DCOMP/UFSJ
AEDSII
Ordenacao
83
Ordenao Externa
Os algoritmos para ordenao externa devem reduzir o nmero de passadas sobre o arquivo Uma boa medida de complexidade de um algoritmo de ordenao por intercalao o nmero de vezes que um item lido ou escrito na memria auxiliar Os bons mtodos de ordenao geralmente envolvem no total menos do que dez passadas sobre o arquivo
DCOMP/UFSJ
AEDSII
Ordenacao
84
DCOMP/UFSJ
AEDSII
Ordenacao
85
DCOMP/UFSJ
AEDSII
Ordenacao
86
DCOMP/UFSJ
AEDSII
Ordenacao
87
DCOMP/UFSJ
AEDSII
Ordenacao
88
DCOMP/UFSJ
AEDSII
Ordenacao
89