Quicksort Parte2
-
Upload
flavia-gomes -
Category
Documents
-
view
5 -
download
0
description
Transcript of Quicksort Parte2
-
Quicksort bsico
Agora que resolvemos o problema da separao, podemos cuidar do Quicksort
propriamente dito. O algoritmo usa a estratgia da diviso e conquista e tem a aparncia
de um Mergesort ao contrrio:
// A funo recebe um vetor v[p..r], com p r, ou seja, quando o vetor est
vazio.)
Exerccios 3
1. Que acontece se trocarmos p < r por p != r na linha 2 do quicksort? 2. Que acontece se trocarmos j-1 por j na linha 4 do quicksort? Que acontece se
trocarmos j+1 por j na linha 5 do cdigo? 3. Submeta o vetor 77 55 33 99 indexado por 1..4 funo quicksort. Teremos
a seguinte sequncia de invocaes da funo (observe a indentao): 4. quicksort( v,1,4) 5. quicksort( v,1,2) 6. quicksort( v,1,0) 7. quicksort( v,2,2) 8. quicksort( v,4,4)
Repita o exerccio com o vetor 55 44 22 11 66 33 indexado por 1..6.
9. Tail recursion. Verifique que a segunda invocao da funo quicksort (linha 5 do cdigo) pode ser eliminada se trocarmos o if por um while:
10. void quicksrt( int v[], int p, int r) { 11. int j; 12. while (p < r) { 13. j = separa( v, p, r); 14. quicksrt( v, p, j-1); 15. p = j + 1; 16. } 17. }
18. A funo quicksort produz uma ordenao estvel do vetor? 19. Discuta a seguinte implementao do algoritmo Quicksort. A funo s se aplica a
vetores v[p..r] com p < r. 20. void qcksrt( int v[], int p, int r) { 21. int j; 22. j = separa( v, p, r); 23. if (p < j-1) qcksrt( v, p, j-1);
-
24. if (j+1 < r) qcksrt( v, j+1, r); 25. }
26. Formulao alternativa da separao. Suponha dada uma implementao da funo separa que funciona assim: rearranja v[p..r] e devolve um ndice j tal que v[p..j] v[j+1..r]. Escreva uma verso do algoritmo Quicksort que use essa implementao do separa. Que restries devem ser impostas sobre j?
27. Verso Iterativa. Escreva uma verso no recursiva do algoritmo Quicksort. [Soluo] 28. Quicksort Aleatorizado. Escreva uma verso aleatorizada (= randomized) do algoritmo
Quicksort.
Animaes do Quicksort
Animao do Quicksort produzida por Mike Bostock (veja tambm uma visualizao esttica, uma variante, e uma outra forma de visualizao).
Sorting Algorithms Animation by David R. Martin. Demonstrao animada do Quicksort, copiada da pgina da disciplina COS226 de
R. Sedgewick (Universidade de Princeton). Animao de algoritmos de ordenao de Nicholas Andr Pinho de Oliveira. Quick-sort with Hungarian (Kkllmenti legnyes) folk dance, created at Sapientia
University (Romania).
Desempenho do Quicksort bsico
O consumo de tempo da funo quicksort proporcional ao nmero de comparaes
entre elementos do vetor. Se o ndice j devolvido por separa estiver sempre mais ou
menos a meio caminho entre p e r, o nmero de comparaes ser aproximadamente n
log n, sendo n o nmero de elementos do vetor. Se o vetor j estiver ordenado ou quase ordenado, o nmero de comparaes estar na ordem de
n2.
Portanto, o pior caso do Quicksort no melhor que o dos algoritmos elementares.
Felizmente, o pior caso muito raro: em mdia, o consumo de tempo do quicksort
proporcional a
n log n .
(Veja detalhes na minha pgina Anlise do Quicksort.)
Altura da pilha de execuo do Quicksort
Na verso bsica do Quicksort, o cdigo cuida imediatamente do subvetor v[p..j-1] e
trata do subvetor v[j+1..r] somente depois que v[p..j-1] estiver ordenado.
Dependendo do valor de j nas sucessivas invocaes da funo, a pilha de execuo
pode crescer muito, atingindo altura igual ao nmero de elementos do vetor. (Isso
acontece, por exemplo, se o vetor estiver em ordem decrescente.) O fenmeno no
afeta o consumo de tempo do algoritmo, mas pode esgotar o espao de memria. Para
controlar o crescimento da pilha de execuo preciso tomar duas providncias:
-
1. cuidar primeiro do menor dos subvetores v[p..j-1] e v[j+1..r] e 2. eliminar a segunda invocao recursiva da funo (veja exerccio acima).
Se adotarmos estas providncias, o tamanho do subvetor que est no topo da pilha de
execuo ser menor que a metade do tamanho do subvetor que est logo abaixo na
pilha. De modo mais geral, o subvetor que est em qualquer das posies da pilha de
execuo ser menor que metade do subvetor que est imediatamente abaixo. Assim, se
a funo for aplicada a um vetor com n elementos, a altura da pilha no passar de log
n.
// A funo rearranja o vetor v[p..r], com p
-
18. } 19. quick_FlipFlop( v, p, i-1); 20. quick_FlipFlop( v, i+1, r); 21. } 22. }
23. A verso abaixo (veja livro de Cormen, Leiserson e Rivest) comea por rearranjar v[p..r] de modo que v[p..j] v[j+1..r] e p j < r (compare com o resultado da separao feita acima). Note que os vetores v[p..j] e v[j+1..r] so ambos estritamente menores que o vetor original.
24. // A funo rearranja o vetor v[p..r], com p c); 35. do ++i; while (v[i] < c); 36. if (i >= j) break; 37. t = v[i], v[i] = v[j], v[j] = t; 38. } 39. quick_CLR( v, p, j); 40. quick_CLR( v, j+1, r); 41. } 42. }
43. Eis outra implementao. (Se no me engano, ela est no livro de Sedgewick.) 44. // A funo rearranja o vetor v[p..r], com p
-
70. while (v[++i] < c) ; 71. while (c < v[--j]) if (j == p) break; 72. if (i > j) break; 73. troca( v[i], v[j]); 74. } 75. troca( v[i], v[r]); 76. quick_S2( v, p, j); 77. quick_S2( v, i+1, r);
}
}