Pesquisa e Ordenação - Aula 03 - Métodos de Ordenação (Troca - Bubble sort)
Merge Sort
-
Upload
flavia-gomes -
Category
Documents
-
view
4 -
download
0
description
Transcript of Merge Sort
-
Mergesort: ordenao por intercalao
Nosso problema: Rearranjar um vetor v[0 .. n-1] de tal modo que ele fique em
ordem crescente, ou seja, de tal modo que tenhamos v[0] . . . v[n-1].
J analisamos alguns algoritmos simples para esse problema que consomem tempo
proporcional a n2. Vamos examinar agora um algoritmo mais complexo mas bem mais
rpido.
Intercalao de vetores ordenados
Antes de resolver nosso problema principal preciso resolver o seguinte problema da
intercalao (= merge): dados vetores crescentes v[p .. q-1] e v[q .. r-1],
rearranjar v[p .. r-1] em ordem crescente.
p q-1 q r-1
111 333 555 555 777 999 999
222 444 777 888
fcil resolver o problema em tempo proporcional ao quadrado de r-p: basta ordenar
o vetor v[p..r-1] sem dar ateno ao estado ordenado das duas metades. Mas isso
muito lento.
Para obter um algoritmo mais rpido, ser preciso usar uma rea de trabalho,
digamos w, do mesmo tipo e mesmo tamanho que o vetor v[p..r-1].
// A funo recebe vetores crescentes v[p..q-1]
// e v[q..r-1] e rearranja v[p..r-1] em ordem
// crescente.
void
intercala1( int p, int q, int r, int v[])
{
int i, j, k, *w;
w = mallocc( (r-p) * sizeof (int));
i = p; j = q;
k = 0;
while (i < q && j < r) {
if (v[i]
-
consumo de tempo tambm proporcional ao nmero de movimentaes, ou seja,
cpias de elementos do vetor de um lugar para outro. Esse nmero igual a 2(r-p).
Resumindo, o consumo de tempo da funo
proporcional a r - p ,
ou seja, proporcional ao tamanho do vetor v[p..r-1].
Exerccios 1
1. A funo intercala1 est correta quando p igual a q, ou seja, quando o vetor
v[p..q-1] est vazio? quando q igual a r, ou seja, quando o vetor v[q..r-1]
est vazio?
2. Analise e discuta a seguinte alternativa para a funo intercala1 (a alocao e liberao de memria foram omitidas):
3. i = p; j = q; k = 0; 4. while (i < q && j < r) { 5. if (v[i] v[j]) w[k++] = v[j++]; 7. } 8. while (i < q) w[k++] = v[i++]; 9. while (j < r) w[k++] = v[j++]; 10. for (i = p; i < r; ++i) v[i] = w[i-p];
11. Analise e discuta a seguinte alternativa para a funo intercala1 (a alocao e liberao de memria foram omitidas):
12. i = p; j = q; k = 0; 13. while (i < q && j < r) { 14. if (v[i] = r || (i < q && v[i]
-
resultado da intercalao dos dois vetores dados. ( claro que z estar em ordem
crescente.) Escreva duas verses da funo: uma iterativa e uma recursiva.
38. Critique a funo de intercalao abaixo. (Observe que a funo faz a intercalao in loco, ou seja, no usa um vetor auxiliar.) Ela est correta? Quais
os invariantes do while? Qual o consumo de tempo? 39. int i, k, t; 40. i = p; 41. while (i < q && q < r) { 42. if (v[i] >= v[q]) { 43. t = v[q]; 44. for (k = q - 1; k >= i; --k) 45. v[k+1] = v[k]; 46. v[i] = t; 47. ++q; 48. } 49. ++i; 50. }
51. Um algoritmo de intercalao estvel se no altera a posio relativa de
elementos iguais. A funo intercala1 discutida acima estvel? E se a
comparao v[i]
-
Exerccios 2
1. Critique a seguinte implementao da funo intercala2. (Suponha que MAX
uma constante definida por um #define.) 2. int w[MAX], i, j, k; 3. for (i = p; i < q; ++i) w[i] = v[i]; 4. for (j = q; j < r; ++j) w[r+q-j-1] = v[j]; 5. i = p; j = r-1; 6. for (k = p; k < r; ++k) 7. if (w[i] < w[j]) v[k] = w[i++]; 8. else v[k] = w[j--];
9. [Sedgewick 8.6] Mostre que a funo intercala2 discutida acima no estvel. Que modificaes preciso introduzir para que ela se torne estvel?
Mergesort
Agora podemos usar qualquer das funes intercala discutidas acima para escrever
um algoritmo rpido de ordenao: o algoritmo recebe um vetor v[p..r-1] e rearranja
o vetor em ordem crescente. O algoritmo recursivo. A base da recurso o caso p
r-1; nesse caso, o vetor tem no mximo 1 elemento e portanto no preciso fazer nada.
// A funo mergesort rearranja o vetor v[p..r-1]
// em ordem crescente.
void
mergesort( int p, int r, int v[])
{
if (p < r-1) {
int q = (p + r)/2;
mergesort( p, q, v);
mergesort( q, r, v);
intercala( p, q, r, v);
}
}
(O resultado da diviso por 2 na expresso (p+r)/2 automaticamente truncado. Por
exemplo, (3+6)/2 vale 4.) Para rearranjar o vetor v[0..n-1] em ordem crescente
basta executar mergesort( 0, n, v).
0 1 2 3 4 5 6 7 8 9 10
111 999 222 999 333 888 444 777 555 666 555
111 999 222 999 333
888 444 777 555 666 555
111 999
222 999 333
888 444 777
555 666 555
.
.
.
111 999
222 333 999
444 777 888
555 555 666
111 222 333 999 999
444 555 555 666 777 88
8
111 222 333 444 555 555 666 777 888 999 999
-
Exerccios 3
1. Considere a funo mergesort discutida acima. Que acontece se trocarmos
(p+r)/2 por (p+r-1)/2? Que acontece se trocarmos (p+r)/2 por (p+r+1)/2?
2. Submeta funo mergesort um vetor indexado por 1..4. Teremos a seguinte sequncia de invocaes da funo (observe a indentao):
3. mergesort( 1,5,v) 4. mergesort( 1,3,v) 5. mergesort( 1,2,v) 6. mergesort( 2,3,v) 7. mergesort( 3,5,v) 8. mergesort( 3,4,v) 9. mergesort( 4,5,v)
Repita o exerccio com um vetor indexado por 1..5.