Escolar Documentos
Profissional Documentos
Cultura Documentos
O problema da separao
O ncleo do algoritmo Quicksort o seguinte problema da separao (= partition
subproblem), que formularemos de maneira propositalmente vaga:
rearranjar um vetor v[p..r] de modo que todos os elementos pequenos fiquem na
parte esquerda do vetor e todos os elementos grandes fiquem na parte direita.
O ponto de partida para a soluo deste problema a escolha de um piv, digamos c. Os
elementos do vetor que forem maiores que c sero considerados grandes e os demais
sero considerados pequenos. importante escolher c de tal modo que as duas partes
do vetor rearranjado sejam estritamente menores que o vetor todo. A dificuldade est
em resolver o problema da separao de maneira rpida sem usar muito espao de
trabalho.
O problema da separao admite muitas formulaes concretas. Eis uma primeira:
rearranjar v[p..r] de modo que tenhamos
v[p..j]
v[j+1..r]
para algum j em p..r. Esta pgina usa a segunda formulao; outras formulaes so
mencionadas nos exerccios.
Exerccios 1
O algoritmo da separao
Eis como D. Gries escreve o algoritmo da separao:
int separa( int v[], int p, int r)
{
int c = v[p], i = p+1, j = r, t;
while (1) {
while (i <= r && v[i] <= c) ++i;
while (c < v[j]) --j;
if (i >= j) break;
t = v[i], v[i] = v[j], v[j] = t;
++i; --j;
}
v[p] = v[j], v[j] = c;
return j;
//
//
//
//
//
//
//
//
//
//
1
2
3
4
5
6
7
8
9
10
A funo rearranja o vetor v[p..r] e devolve um elemento j do conjunto p..r tal que
v[p..j-1]
Gostaramos que j ficasse a meio caminho entre p e r, mas devemos estar preparados
para aceitar os casos extremos j == p e j == r .
p
ccccc>c>c>c>c>c
Algumas perguntas que chamam a ateno para detalhes importantes: Que acontece se
executarmos a funo com p igual a r? Que acontece se eliminarmos i <= r na
linha 3? Por que no h um j >= p na linha 4? Que acontece se escrevermos i > j na
linha 5? Que acontece se trocarmos j por i nas linhas 9 e 10?
Anlise do algoritmo da separao
No incio de cada iterao, ou seja, a cada passagem pelo ponto A, temos a seguinte
configurao:
p
i=j
ccccc?
>c>c>c>c
i == j+1
p j r
v[p+1..j] c e v[j+1..r] > c.
Exerccios 2
1. Qual o resultado da funo separa quando os elementos de v[p..r] so todos
iguais? E quando v[p..r] crescente? E quando v[p..r] decrescente?
E quando cada elemento de v[p..r] tem um de dois valores possveis?
2. A funo separa produz um rearranjo estvel do vetor, ou seja, preserva a ordem
relativa de elementos de mesmo valor?
3. Analise e discuta a seguinte verso da funo separa. Ela equivalente do livro de
Cormen, Leiserson, Rivest e Stein.
4. int separa_CLRS( int v[], int p, int r) {
5.
int c = v[r], i = p, j, t;
6.
for (j = p; j < r; ++j) {
7.
if (v[j] <= c) {
8.
t = v[i], v[i] = v[j], v[j] = t;
9.
++i;
10.
}
11.
}
12.
t = v[i], v[i] = v[r], v[r] = t;
13.
return i;
14. }
25.
26.
27. }
E. Roberts.
45. int separa_R( int v[], int p, int r) {
46.
int c = v[p], i = p+1, j = r, t;
47.
while (1) {
48.
while (i < j && c < v[j]) --j;
49.
while (i < j && v[i] <= c) ++i;
50.
if (i == j) break;
51.
t = v[i], v[i] = v[j], v[j] = t;
52.
}
53.
if (v[i] > c) return p;
54.
v[p] = v[i], v[i] = c;
55.
return i;
56. }