Escolar Documentos
Profissional Documentos
Cultura Documentos
7 SortB PDF
7 SortB PDF
AED (IST/DEEC) 57
Quicksort [2]
Algoritmo do tipo dividir para conquistar
AED (IST/DEEC) 58
Quicksort [3]
void quicksort(Item a[], int l, int r)
{
int i;
if (r <= l) return;
i = partition(a, l, r);
quicksort(a, l, i-1);
quicksort(a, i+1, r);
}
AED (IST/DEEC) 59
Quicksort [4]
ASORTINGEXAMPLE
AAEETINGOXSMPLR
AAE
AA
A
LINGOPMRXTS
LIGMOPN
GIL
IL
I
NPO
OP
P
STX
TX
T
AAEEGILMNOPRSTX
AED (IST/DEEC) 60
Quicksort - Partio [1]
Processo de partio rearranja os dados de forma a que as trs condies
seguintes sejam vlidas (de a[l] a a[r]):
o elemento a[i], para algum i, fica, aps a partio, na sua posio final
nenhum dos elementos em a[l] a[i-1] maior do que a[i]
nenhum dos elementos em a[i+1] a[r] menor do que a[i]
Processo coloca pelo menos um elemento na sua posio final
possvel uma demonstrao por induo para o processo recursivo
AED (IST/DEEC) 61
AED (IST/DEEC) 62
Quicksort - Partio [3]
ASORTINGEXAMPLE
AS
AMPL
AA SMPLE
O
EX
AAE OXSMPLE
R
ERTING
AAEETINGOXSMPLR
AED (IST/DEEC) 63
AED (IST/DEEC) 64
Quicksort - Partio [5]
int partition(Item a[], int l, int r)
{
int i, j;
Questes:
Item v;
dever parar-se a busca em chaves
iguais a v?
v = a[r]; i = l-1; j = r;
Deveria haver sentinelas para
for (;;) {
testar os limites da tabela?
while (less(a[++i], v)) ;
Detalhes do cruzamento de
while (less(v, a[--j]))
if (j == l) break; ndices so muito importantes
if (i >= j) break;
exch(a[i], a[j]);
}
exch(a[i], a[r]);
return i;
}
AED (IST/DEEC) 65
AED (IST/DEEC) 66
Quicksort - Caractersticas [1]
Pode ser muito ineficiente em casos patolgicos
AED (IST/DEEC) 67
CN = 2 CN/2 + N
10 termo cobre o custo de ordenar os dois sub-ficheiros
20 termo refere-se a examinar cada elemento
AED (IST/DEEC) 68
Quicksort - Caractersticas [3]
Propriedade: quicksort usa cerca de 2N lg N comparaes em mdia
1
CN = N + 1 + ( Ck 1 + CN k )
N 1k N
N 2, C0 = C1 = 0
termo N+1 cobre o custo de comparar o elemento de partio com os
restantes (2 comparaes extra: ponteiros cruzam-se)
resto vem do facto de que cada elemento tem probabilidade 1/N de ser o
elemento de partio aps o que ficamos com duas sub-tabelas de
tamanhos k-1 e N-k
AED (IST/DEEC) 69
AED (IST/DEEC) 70
Ordenao Sntese da Aula O5
Algoritmo quicksort
Ideia chave + Motivao
Algoritmo que recorre diviso em instncias menores divide and
conquer
Cdigo
Exemplo de aplicao
Descrio detalhada do mecanismo de partio
Anlise de eficincia
Pior caso
Melhor caso
Caso mdio
AED (IST/DEEC) 71
AED (IST/DEEC) 72
Quicksort - Caractersticas [6]
Questes mais relevantes:
possvel reduo de desempenho devido ao uso de recurso
tempo de execuo dependente dos dados de entrada
tempo de execuo quadrtico no pior caso
um problema
espao/memria necessrio no pior caso linear
um problema srio (para ficheiros de grandes dimenses)
Problema do espao est associado ao uso de recurso:
recurso implica chamada a funo e logo a carregar dados na pilha/stack
do computador
no pior caso todas as parties degeneram e h O(N) nveis de recurso
pilha cresce at ordem N !!!
AED (IST/DEEC) 73
AED (IST/DEEC) 74
Quicksort - Espao necessrio [2]
Usamos uma pilha (stack) explcita
pilha contm trabalho a ser processado, na forma de sub-tabelas a ordenar
quando precisamos de uma sub-tabela para processar tiramo-la da pilha (i.e.
fazemos um pop() do stack)
por cada partio criamos duas sub-tabelas e metemos ambas na pilha (i.e.
fazemos dois push() para o stack)
substitui a pilha do computador que usado na implementao recursiva
Conduz a uma verso no recursiva de quicksort()
verifica os tamanhos das duas sub-tabelas e pe a maior delas primeiro na
pilha (e a menor depois; logo a menor retirada e tratada primeiro)
ordem de processamento das sub-tabelas no afecta a correcta operao da
funo ou o tempo de processamento mas afecta o tamanho da pilha
AED (IST/DEEC) 75
AED (IST/DEEC) 76
Quicksort - Verso no-recursiva [1]
#define push2(A, B) push(A); push(B);
AED (IST/DEEC) 77
AED (IST/DEEC) 78
Ordenao Sntese da Aula O6
Anlise do algoritmo quicksort
AED (IST/DEEC) 79
AED (IST/DEEC) 80
Quicksort - Melhoramentos [2]
Pequenos ficheiros/sub-tabelas
um programa recursivo garantido instanciar-se a si prprio mltiplas vezes para
pequenos ficheiros!
conveniente utilizar o melhor mtodo possvel quando encontra tais ficheiros
forma bvia de obter este comportamento mudar o teste no incio da funo
recursiva para uma chamada a insertion sort
if (r-l <= M) insertion(a, l, r)
em que M um parmetro a definir na implementao
outra soluo a de simplesmente ignorar ficheiros pequenos (tamanho menor que M)
durante a partio:
if (r-l <= M) return;
neste caso no final teremos um ficheiro que est praticamente todo ordenado
AED (IST/DEEC) 81
AED (IST/DEEC) 82
Quicksort - Melhoramentos [4]
Mtodo da mdia de trs melhora quicksort por trs razes
o pior caso mais improvvel de acontecer na prtica
dois dos trs elementos teriam de ser dos maiores ou menores do ficheiro
e isto teria de acontecer constantemente a todos os nveis de partio
elimina o uso de uma sentinela para a partio
esta funo pode ser feita por um dos trs elementos analisados
reduz o tempo mdio de execuo do algoritmo
embora apenas por cerca de 5%
caso particular de mtodos em que se faz amostragem dos dados para estimar as suas
propriedades
junto com o mtodo de tratar de pequenos ficheiros pode dar ganhos de 20 a 25%
AED (IST/DEEC) 83
Mediana de trs
AED (IST/DEEC) 84
Quicksort - Melhoramentos [6]
bastante melhor do que parece!!
AED (IST/DEEC) 85
12500 6 2 2 2 3 2 3
25000 10 5 5 5 5 4 6
50000 26 11 10 10 2 9 14
100000 58 24 22 22 25 20 28
200000 126 53 48 50 52 44 54
400000 278 116 105 110 114 97 118
800000 616 255 231 241 252 213 258
Quicksort cerca de 2 vezes mais rpido que shellsort para ficheiros grandes
aleatoriamente ordenados.
Usando insertion para pequenos ficheiros e a estratgia de mediana-de-trs
melhoram cada um a eficincia por um factor de 10%
AED (IST/DEEC) 86
Quicksort - Chaves duplicadas [1]
Ficheiros com um grande nmero de chaves duplicadas so frequentes
na prtica
desempenho de quicksort pode ser substancialmente melhorado
se todas as chaves forem iguais
quicksort mesmo assim faz N lg N comparaes
se houver duas chaves distintas
reduz-se ao problema anterior para cada sub-ficheiro
melhor completar a ordenao com uma nica partio
natureza recursiva de quicksort garante que haver frequentemente sub-
ficheiros de items com poucas chaves
uma possibilidade dividir o ficheiro em trs partes
cada uma para chaves menores, iguais e maiores que o elemento de partio
no trivial de implementar, sobretudo se se impuser que a ordenao dever
ser feita com apenas uma passagem pelos dados
AED (IST/DEEC) 87
AED (IST/DEEC) 88
Quicksort - Partio em trs [1]
#define eq(A,B) (!less(A,B) && !less(B,A))
void quicksort(Item a[], int l, int r)
{
int i, j, k, p, q;
Item v;
if (r <= l) return;
v = a[r]; i = l-1; j = r; p = l-1; q = r;
for (;;) {
while (less(a[++i], v)) ;
while (less(v, a[--j])) if (j == l) break;
if (i >= j) break;
exch(a[i], a[j]);
if (eq(a[i],v)) {
p++; exch(a[p],a[i]);
}
if (eq(v,a[j])) {
q--; exch(a[q],a[j]);
}
}
exch(a[i], a[r]); j = i-1; i = i+1;
for (k = l ; k < p; k++, j--) exch(a[k], a[j]);
for (k = r-1; k > q; k--, i++) exch(a[k], a[i]);
quicksort(a, l, j);
quicksort(a, i, r);
}
AED (IST/DEEC) 89
Seleco [1]
uma operao importante relacionada com ordenao mas para a
qual uma ordenao completa no necessria
exemplo calculo de mediana de um conjunto de dados
ou muitas outras operaes estatsticas ou de amostragem
com generalidade pode ser descrito como o problema de encontrar o
conjunto dos k-menor nmeros
ex: seja a tabela [ 15, 3, 47, 9, 12, 0 ]. O 3o menor elemento o 9
AED (IST/DEEC) 90
Seleco [2]
Partio coloca um elemento na sua posio final: i
elementos esquerda so menores que a[i]
elementos direita so maiores que a[i]
AED (IST/DEEC) 91
AED (IST/DEEC) 92
Juno versus partio [1]
Quicksort como vimos baseado na operao de seleco
fazer seleco semelhante a dividir um ficheiro em duas partes
efectuada uma partio e quando as duas metades do ficheiro
esto ordenadas, o ficheiro est ordenado
Operao complementar de juno ( merge )
combinar dois ficheiros para obter um, maior, ordenado
dividir os ficheiros em duas partes para serem ordenados e depois
combinar as partes de forma a que o ficheiro total fique ordenado
mergesort
AED (IST/DEEC) 93
ARSTGIN
ARSTNIG
ARSTNIGA
ARSTNI AG
ARSTN AGI
ARST AGIN
ARST AGINR
ARST AGINRS
ARS AGINRST
AED (IST/DEEC) 96
Mergesort
ASORTINGEXAMPLE
AS
ASOR
Ordenar um ficheiro: AORS
IT
ordenando duas GN
metades do mesmo GINT
(recursivamente) e AGINORST
EX
depois fazendo a AM
juno dos resultados AEMX
LP
ELP
AEELMPX
AAEEGILMNOPRSTX
AED (IST/DEEC) 97
Implementao de mergesort -
Verso recursiva (descendente)
Para ordenar um ficheiro (processo top-down mergesort)
divide-se em duas metades
ordenam-se essas metades (recursivamente)
faz-se a juno dos resultados
if (r <= l) return;
mergesort(a, l, m);
mergesort(a, m+1, r);
merge(a, l, m, r);
}
AED (IST/DEEC) 98
Mergesort - Propriedades
Complexidade garantidamente N log N
mas requer espao extra proporcional a N
dados apenas definem a ordem em que os elementos so processados
nas junes
complexidade garantida pode ser um problema
no pode haver nenhum caso melhor
no se pode adaptar consoante os dados
um algoritmo estvel
(se a juno o for)
propriedade que muitas vezes faz com que seja escolhido!
Normalmente implementado de forma a aceder aos dados
sequencialmente
por vezes o nico processo de acesso
muito usado para ordenao de listas ligadas
AED (IST/DEEC) 99
Implementao de mergesort -
Verso no-recursiva (ascendente)
Tal como em quicksort tambm h uma verso no-recursiva de
mergesort (computaes efectuadas por outra ordem)
sub-ficheiros so processados independentemente, logo junes
podem ser feitas numa sequncia diferente
mesmo conjunto de divises e de junes
apenas as junes so efectuadas por outra ordem
primeiro as de ficheiros com um elemento, depois as de 2 elementos, etc
em cada passo o tamanho dos sub-ficheiros ordenados duplica
Implementao: no livro...
AED (IST/DEEC) 100
Mergesort - Exemplo Grfico
Mergesort ascendente (cima) consiste numa srie de
passagens pelo ficheiro fazendo a juno de sub-ficheiros
ordenados at apenas existir um
Mergesort descendente (baixo) ordena a primeira metade
do ficheiro antes de prosseguir para a outra metade
(recursivamente)