Professional Documents
Culture Documents
4 Ordenao
Ordenao
Introduo - Conceitos Bsicos Ordenao Interna Ordenao por Seleo Ordenao por Insero Shellsort Quicksort Heapsort Ordenao Parcial Seleo Parcial Insero Parcial Heapsort Parcial Quicksort Parcial Ordenao Externa
ltima alterao: 10 de Outubro de 2006
Ordenao
Intercalao Balanceada de Vrios Caminhos Implementao por meio de Seleo por Substituio Consideraes Prticas Intercalao Polifsica Quicksort Externo
elaboradas por Fabiano C. Botelho, Leonardo Rocha, Leonardo Mata e Nivio Ziviani
Transparncias
Deve-se ampliar a interface Item sempre que houver necessidade de manipular a chave de um registro. O mtodo compara sobrescrito para determinar como so comparados dois objetos da classe MeuItem . Os mtodos alteraChave e recuperaChave so sobrescritos para determinar como alterar e como recuperar o valor da chave de um objeto da classe MeuItem .
10
11
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.
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.
12
13
Ordenao Interna
A classe mostrada a seguir apresenta os mtodos de ordenao interna que sero estudados. Utilizaremos um vetor v de registros do tipo Item e uma varivel inteira n com o tamanho de v . O vetor contm registros nas posies de 1 at n, e a 0 utilizada para sentinelas.
package cap4. ordenacaointerna ; import cap4. Item ; / / vide transparncia 6
public class Ordenacao { public static void selecao ( Item v [ ] , int n) public static void insercao ( Item v [ ] , int n) public static void shellsort ( Item v [ ] , int n) public static void quicksort ( Item v [ ] , int n) public static void heapsort ( Item v [ ] , int n) } Chaves iniciais: i=1 i=2 i=3 i=4 i=5 O A A A A A
14
15
n 2
M (n) = 3(n 1) A atribuio min = j executada em mdia n log n vezes, Knuth (1973).
16
17
A colocao do item no seu lugar apropriado na seqncia destino realizada movendo-se itens com chaves maiores para a direita e ento inserindo o item na posio deixada vazia.
18
19
Assumindo que todas as permutaes de n so igualmente provveis no caso mdio, temos: melhor caso : C (n) = (1 + 1 + + 1) = n 1 pior caso caso m edio : C (n) = (2 + 3 + + n) = : C (n) =
n 1 2 1 (3 + 4 + 2 n n2 + 34 1 4 n2 + 2
+ n + 1) =
20
21
+ n + 3) =
22
23
Shellsort
Proposto por Shell em 1959. uma extenso do algoritmo de ordenao por insero. Problema com o algoritmo de ordenao por insero: Troca 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.
Shellsort
Os itens separados de h posies so rearranjados. Todo h-simo item leva a uma seqncia ordenada. Tal seqncia dita estar h-ordenada. Exemplo de utilizao:
1 Chaves iniciais: h=4 h=2 h=1 O N D A 2 R A A D 3 D D N E 4 E E E N 5 N O O O 6 A R R R
24
25
Shellsort
Como escolher o valor de h: Seqncia para h: h(s) = 3h(s 1) + 1, para s > 1 h(s) = 1, para s = 1.
Shellsort
public static void shellsort ( Item v [ ] , int n) { int h = 1; do h = h 3 + 1; while (h < n) ; do { h /= 3; for ( int i = h + 1; i <= n ; i ++) { Item x = v [ i ] ; int j = i ; while ( v [ j h ] .compara ( x) > 0) { v [ j ] = v [ j h ] ; j = h; i f ( j <= h) break ; } v[ j ] = x; } } while (h ! = 1 ) ; }
Knuth (1973, p. 95) 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, . . .
A implementao do Shellsort no utiliza registros sentinelas. Seriam necessrios h registros sentinelas, uma para cada h-ordenao.
26
27
Shellsort
Anlise 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 seqncia 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: Conjetura 1 : C (n) = O(n1,25 ) Conjetura 2 : C (n) = O(n(ln n)2 )
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,
28
29
Quicksort
Proposto por Hoare em 1960 e publiccado 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.
Quicksort
A parte mais delicada do mtodo relativa ao mtodo particao . O vetor v [esq ..dir ] rearranjado por meio da escolha arbitrria de um piv x. O vetor v particionado em duas partes: A parte esquerda com chaves menores ou iguais a x. A parte direita com chaves maiores ou iguais a x.
30
31
Quicksort
Algoritmo para o particionamento: 1. Escolha arbitrariamente um piv x. 2. Percorra o vetor a partir da esquerda at que v [i] x. 3. Percorra o vetor a partir da direita at que v [j ] x. 4. Troque v [i] com v [j ]. 5. Continue este processo at os apontadores i e j se cruzarem. Ao nal, o vetor v [esq ..dir ] est particionado de tal forma que: Os itens em v [esq ], v [esq + 1], . . . , v [j ] so menores ou iguais a x. Os itens em v [i], v [i + 1], . . . , v [dir ] so maiores ou iguais a x.
Quicksort
Ilustrao do processo de partio:
1 O A A 2 R R D 3 D D R 4 E E E 5 N N N 6 A O O
O piv x escolhido como sendo v [(i + j ) / 2]. Como inicialmente i = 1 e j = 6, ento x = v [3] = D. Ao nal do processo de partio i e j se cruzam em i = 3 e j = 2.
32
33
Quicksort
Mtodo Partio:
private static class LimiteParticoes { int i ; int j ; } private static LimiteParticoes particao (Item v [ ] , int esq, int dir ) { LimiteParticoes p = new LimiteParticoes ( ) ; p. i = esq ; do { while ( x .compara ( v [p. i ] ) > 0 ) p. i ++; while ( x .compara ( v [p. j ] ) < 0 ) p. j ; i f (p. i <= p. j ) { Item w = v [p. i ] ; v [p. i ] = v [p. j ] ; v [p. j ] = w; p. i ++; p. j ; } } while (p. i <= p. j ) ; return p; } p. j = dir ; Item x = v [ (p. i + p. j ) / 2 ] ; / / obtm o pivo x
Quicksort
Mtodo ordena e algoritmo Quicksort :
private static void ordena ( Item v [ ] , int esq, int dir ) { LimiteParticoes p = particao ( v , esq, dir ) ; i f (esq < p. j ) ordena ( v , esq, p. j ) ; i f (p. i < dir ) ordena ( v , p. i , dir ) ; } public static void quicksort ( Item v [ ] , int n) { ordena ( v , 1 , n) ; }
O modicador private nessa classe encapsula os mtodos para serem utilizados somente dentro da classe Ordenacao . O anel interno do procedimento Particao extremamente simples. Razo pela qual o algoritmo Quicksort to rpido.
34
35
Quicksort
Exemplo do estado do vetor em cada chamada recursiva do procedimento Ordena:
Quicksort
Anlise Seja C (n) a funo que conta o nmero de comparaes. Pior caso: C (n) = O(n2 ) O pior caso ocorre quando, sistematicamente, o piv escolhido como sendo um dos extremos de um arquivo j ordenado. Isto faz com que o procedimento Ordena seja chamado recursivamente n vezes, eliminando apenas um item em cada chamada. O pior caso pode ser evitado empregando pequenas modicaes no algoritmo. Para isso basta escolher trs itens quaisquer do vetor e usar a mediana dos trs como piv.
Chaves iniciais: 1 2 3 4 5
O A A
R D D
D R E
E E
N N
A O
R N
N R O
O O R R
36
37
Quicksort
Anlise Melhor caso: C (n) = 2C (n/2) + n = n log n n + 1 Esta situao ocorre quando cada partio divide o arquivo em duas partes iguais. Caso mdio de acordo com Sedgewick e Flajolet (1996, p. 17): C (n) 1, 386n log n 0, 846n, Isso signica que em mdia o tempo de execuo do Quicksort O(n log n).
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: Tem um pior caso O(n2 ) comparaes. Sua implementao muito delicada e difcil: Um pequeno engano pode levar a efeitos inesperados para algumas entradas de dados. O mtodo no estvel.
38
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.
Heapsort
Filas de Prioridades uma estrutura de dados onde a chave de cada item reete sua habilidade relativa de abandonar o conjunto de itens rapidamente. Aplicaes: SOs usam las de prioridades, nas quais as chaves representam o tempo em que eventos devem ocorrer. Mtodos numricos iterativos so baseados na seleo repetida de um item com maior (menor) valor. Sistemas de gerncia de memria usam a tcnica de substituir a pgina menos utilizada na memria principal por uma nova pgina.
40
41
Heapsort
Filas de Prioridades - Tipo Abstrato de Dados Operaes: 1. Constri uma la de prioridades a partir de um conjunto com n itens. 2. Informa qual o maior item do conjunto. 3. Retira o item com maior chave. 4. Insere um novo item. 5. Aumenta o valor da chave do item i para um novo valor que maior que o valor atual da chave. 6. Substitui o maior item por um novo item, a no ser que o novo item seja maior. 7. Altera a prioridade de um item. 8. Remove um item qualquer. 9. Ajunta duas las de prioridades em uma nica.
Heapsort
Filas de Prioridades - Representao Representao atravs de uma lista linear ordenada: Neste caso, Constri leva tempo O(n log n). Insere O(n). Retira O(1). Ajunta O(n). Representao atravs de uma lista linear no ordenada: Neste caso, Constri tem custo linear. Insere O(1). Retira O(n). Ajunta O(1) para apontadores e O(n) para arranjos.
42
43
Heapsort
Filas de Prioridades - Representao A melhor representao atravs de uma estruturas de dados chamada heap: Neste caso, Constri O(n). Insere, Retira, Substitui e Altera so O(log n). Observao: Para implementar a operao Ajunta de forma eciente e ainda preservar um custo logartmico para as operaes Insere, Retira, Substitui e Altera necessrio utilizar estruturas de dados mais sosticadas, tais como rvores binomiais (Vuillemin, 1978).
Heapsort
Filas de Prioridades - Algoritmos de Ordenao As operaes das las de prioridades podem ser utilizadas para implementar algoritmos de ordenao. Basta utilizar repetidamente a operao Insere para construir a la de prioridades. Em seguida, utilizar repetidamente a operao Retira para receber os itens na ordem reversa. O uso de listas lineares no ordenadas corresponde ao mtodo da seleo. O uso de listas lineares ordenadas corresponde ao mtodo da insero. O uso de heaps corresponde ao mtodo Heapsort .
44
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:
1 S
Heapsort
Heaps As chaves na rvore satisfazem a condio do heap. As chaves em cada n s ao maiores 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 arranjo:
1
2 R O 3
2 R
3 O
4 E
5 N
6 A
7 D
S
7
4 E
5 N
A representao extremamente compacta. rvore binria completa: Os ns so numerados de 1 a n. O primeiro n chamado raiz. O n k/2 o pai do n k , para 1 < k n. Os ns 2k e 2k + 1 so os lhos esquerda e direita do n k , para 1 k k/2 . 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 / 2.
46
47
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 v [1], v [2], . . . , v [n]. Os itens v [n/2 + 1], v [n/2 + 2], . . . , v [n] formam um heap: Neste intervalo no existem dois ndices i e j tais que j = 2i ou j = 2i + 1.
Heapsort
Estrutura de dados la de prioridades implementada utilizando um heap
package cap4. ordenacaointerna ; import cap4. Item ; / / vide transparncia 6 public class FPHeapMax { private Item v [ ] ; private int n; public FPHeapMax ( Item v [ ] ) { this . v = v ; this .n = this . v . length 1; } public void refaz ( int esq, int dir ) public void constroi ( ) public Item max ( ) public Item retiraMax ( ) throws Exception public void aumentaChave ( int i , Object chaveNova) throws Exception public void insere ( Item x ) throws Exception }
48
49
Heapsort
Heaps Algoritmo:
1 Chaves iniciais: Esq = 3 Esq = 2 Esq = 1 O O O S 2 R R R R 3 D S S O 4 E E E E 5 N N N N 6 A A A A 7 S D D D
Heapsort
Heaps O Programa que implementa a operao que informa o item com maior chave:
public Item max ( ) { return this . v [ 1 ] ; }
Os itens de v [4] a v [7] formam um heap. O heap estendido para a esquerda (esq = 3), englobando o item v [3], pai dos itens v [6] e v [7]. A condio de heap violada: 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.
50
51
Heapsort
Heaps Mtodo para construir o heap:
/ / Usa o mtodo refaz da transparncia 49 public void constroi ( ) { int esq = n / 2 + 1 ; while (esq > 1) { esq; this . refaz (esq, this .n) ; } }
Heapsort
Heaps Programa que implementa a operao de retirar o item com maior chave:
/ / Usa o mtodo refaz da transparncia 49 public Item retiraMax ( ) throws Exception { Item maximo; i f ( this .n < 1) throw new Exception ( "Erro : heap vazio" ) ; else { maximo = this . v [ 1 ] ; this . v[1] = this . v [ this .n]; refaz ( 1 , this .n) ; } return maximo; }
52
53
Heapsort
Heaps Programa que implementa a operao de aumentar o valor da chave do item i:
public void aumentaChave ( int i , Object chaveNova) throws Exception { Item x = this . v [ i ] ; i f (chaveNova == null ) throw new Exception ( "Erro : chaveNova com valor null " ) ; x . alteraChave (chaveNova) ; while ( ( i > 1) && (x .compara ( this . v [ i / 2 ] ) > = 0 ) ) { this . v [ i ] = this . v [ i / 2 ] ; i /= 2; } this . v [ i ] = x ; }
Heapsort
Heaps Exemplo da operao de aumentar o valor da chave do item na posio i:
(a)
R S
(b)
O R
i
E N S A D E N U
i
U D
(c)
R
(d) i
U R
i
S
54
55
Heapsort
Heaps Programa que implementa a operao de inserir um novo item no heap:
/ / Usa o mtodo aumentaChave da tranparncia 52 public void insere ( Item x ) throws Exception { this .n++; i f ( this .n == this . v . length ) throw new Exception ( "Erro : heap cheio" ) ; Object chaveNova = x .recuperaChave ( ) ; this . v [ this .n] = x ; this . v [ this .n ] . alteraChave (new Integer ( Integer . MIN_VALUE ) ) ; / / this .aumentaChave ( this .n, chaveNova) ; }
Heapsort
Algoritmo: 1. Construir o heap. 2. Troque o item na posio 1 do vetor (raiz do heap) com o item da posio n. 3. Use o procedimento Refaz para reconstituir o heap para os itens v [1], v [2], . . . , v [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.
56
57
Heapsort
Exemplo de aplicao do Heapsort :
1 S R O N E D A 2 R N N E D A D 3 O O A A A E 4 E E E D N 5 N D D O 6 A A R 7 D S
Heapsort
Programa que mostra a implementao do Heapsort para um conjunto de n itens implementado como um vetor do tipo Item :
public static void heapsort ( Item v [ ] , int n) { / / Usa a classe FPHeapMax da transparncia 47 FPHeapMax fpHeap = new FPHeapMax ( v ) ; int dir = n; fpHeap. constroi ( ) ; / / constroi o heap while ( dir > 1 ) { / / ordena o vetor Item x = v [ 1 ] ; v[1] = v [ dir ] ; v [ dir ] = x ; dir ; fpHeap. refaz ( 1 , dir ) ; } }
O caminho seguido pelo procedimento Refaz 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.
Anlise O procedimento Refaz gasta cerca de log n operaes, no pior caso. Logo, Heapsort gasta um tempo de execuo proporcional a n log n, no pior caso.
58
59
Heapsort
Vantagens: 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 . O Heapsort 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.
60
61
62
63
1. O Shellsort bastante sensvel ordenao ascendente ou descendente da entrada; 2. Em arquivos do mesmo tamanho, o Shellsort executa mais rpido para arquivos ordenados. 3. O Quicksort sensvel ordenao ascendente ou descendente da entrada. 4. Em arquivos do mesmo tamanho, o Quicksort executa mais rpido para arquivos ordenados. 5. O Quicksort o mais rpido para qualquer tamanho para arquivos na ordem ascendente. 6. O Heapsort praticamente no sensvel ordenao da entrada.
64
65
66
67
68
69
70