Vous êtes sur la page 1sur 5

http://w3.ualg.pt/~hshah/ped/Aula%2014/Quick_final.

html Quick Sort O Quick Sort um dos mtodo mais rpidos de ordenao, apesar de s vezes parties desequilibradas poderem conduzir a uma ordenao lenta. Esse mtodo de ordenao utiliza a tcnica divide and conquer (dividir o problema inicial em dois subproblemas e resolver um problema menor utilizando a recursividade) Este mtodo baseia-se na diviso da tabela em duas sub-tabelas, dependendo de um elemento chamado piv, normalmente o 1 elemento da tabela. Uma das sub-tabelas contm os elementos menores que o piv enquanto a outra contm os maiores. O piv colocado entre ambas, ficando na posio correcta. As duas sub -tabelas so ordenadas de forma idntica, at que se chegue tabela com um s elemento. Complexidade: caso mdio O(N * log N) Esse mtodo de ordenao divide-se em vrios passos: y Escolher para piv o primeiro elemento da tabela (p=x[1]) y Se os elementos de x forem rearranjados de forma a que o piv (p) sejam colocados na posio j e sejam respeitadas as seguintes condies: 1. todos os elementos entre as posies 1 e j-1 so menores ou iguais que o piv (p) 2. todos os elementos entre as posies j+1 e n so maiores que o piv (p) Ento p permanecer na posio j no final do ordenamento. y Se este processo for repetido para as sub-tabelas x[1] a x[j-1] e x[j+1] a x[n] e para todas as sub-tabelas criadas nas iteraes seguintes obteremos no final uma tabela ordenada. Portanto a parte mais difcil deste mtodo o procedimento parte que divide a tabela em 2 sub-tabelas dependendo do piv. Algoritmo de Ordenao 1. Caso bsico: Se o nmero de elementos a ordenar for 0 ou 1 ento terminar 2. Seleccionar o elemento Piv P : Escolhendo um elemento qualquer entre os elementos a ordenar 3. Processo de partio: Dividir os elementos em 2 subconjuntos disjuntivos na qual: m= (x vector - (P) | x e P) M= (x vector - (P) | x > P) //elementos inferiores ao piv //elementos superiores ao piv

4. Mtodo recursivo: Ordenar os subconjuntos esquerdo e direito, usando o mesmo mtodo recursivamente. Algoritmo de Escolha de Piv y Mtodo Simples: Usar sempre o primeiro elemento da parte do array/vector que est sendo ordenado. y Mtodo Melhor: Olhar para trs elementos diferentes, e usar o elemento mdio entre os trs.

Algoritmo de Partio O procedimento de partio deve reorganizar os elementos de forma a que: 1. Escolha do piv: Considere p=a[lim_inferior] como o elemento piv y Usa-se o primeiro elemento para facilitar a implementao. 2. Dois ponteiros alto e baixo so inicializados como os limites superior e inferior do array/vector a ordenar y Em qualquer ponto de execuo, todos os elementos acima de alto maior do que x e todo o elemento abaixo de baixo menor do que x. 3. Os dois ponteiros alto e baixo so movidos um em direco ao outro da seguinte forma: y Incrementa baixo em uma posio enquanto que a[baixo]e p. y Decremente alto em uma posio enquanto que a[alto] > p. y Se alto > baixo , troque a[baixo] por a[alto]. O processo repetido at que a condio descrita mais acima falhe (quando alto <= baixo ). Neste ponto a[alto]ser trocado por a[lim_Inferior],cuja posio final era procurada, e alto retornado em i.

Implementao:
 Diviso (procedimento) divide a lista em 2; L1 conter todos os elementos menores que o piv e L2 todos os elementos que forem maiores, L0 vai conter um s elemento que o piv  Quick Sort

Em pseudocdigo: P dividir (l, l0, l1, l2, pivo) Se _vazia (l) Ento l0=NULL l1=NULL l2=NULL Seno dividir(l, lo, l1, l2, pivo) Se cabea(l) < pivo Ento l1=criar (cabea(l), l1) Seno Se cabea (l) > pivo Ento l2=criar (cabea(l), l2) Seno l0=criar (cabea(l), l0) Quick_Sort (l) lista Se _vazia(l) Ento devolver NULL Seno Se _vazia(l) Ento devolver l Seno dividir (l, l0, l1, l2, cabea(l)) devolver concatenar (quick_sort(l1), concatenar(l0, quick_sort(l2)))

Exemplos:

Implementao em C++

Vamos considerar um Array de nmeros inteiros, tambm vamos considerar que a varivel tam, do tipo numrica inteira, com o tamanho de nosso Array.

void quick(int Q[50], int inicio, int fim) { int meio; comparacoes[4]++; if (inicio<fim) { atribuicoes[4]++; meio = particiona(Q, inicio, fim); quick(Q, inicio, meio-1); quick(Q, meio+1, fim); } } int particiona(int Q[50], int inicio, int fim) { int pivo, ultbaixo, temp, i; atribuicoes[4]++; pivo = Q[inicio]; ultbaixo = inicio; for(i=inicio+1; i<=fim; i++) { comparacoes[4]++; if (Q[i]<=pivo) { ultbaixo++; atribuicoes[4]+=3; temp = Q[i]; Q[i] = Q[ultbaixo]; Q[ultbaixo] = temp; } }

atribuicoes[4]+=3; temp = Q[inicio]; Q[inicio] = Q[ultbaixo]; Q[ultbaixo] = temp; return(ultbaixo); }

Exerccios:

1 - Considere o caso onde todos os pivs do quick sort dividem a lista numa lista vazia e numa lista que contm todos os elementos maiores que o piv. Este caso degenerado do quick sort equivalente a outro algoritmo de ordenao? Soluo - Sim a ordenao por insero, onde encontra iterativamente os elementos menores dos restantes que ainda no esto ordenados e coloca-os no incio da lista. 2 Explica como o mtodo do piv sofisticado pode ajudar na eficincia do algoritmo do quick sort? Soluo O quick sort executa o algoritmo escolhendo o mtodo do melhor piv. Se todo o piv dividir a lista, aproximadamente, ao meio, a ordenao corre numa complexidade de: O(N * log(N) ). Este mtodo eficiente se a escolha do piv um elemento cujo valor seja mdio relativamente aos restantes.

3 Explique porque que a seguinte lista pouco eficiente no mtodo de ordenao do quick sort. Lista: (9, 8, 7, 6, 5, 4, 3, 2, 1) Soluo Visto que o algoritmo escolhe o primeiro elemento para piv, neste caso, uma m escolha visto que a lista j se encontra ordenada (decrescentemente).

Links:


Para a animao do quick sort

http://utopia.poly.edu/~kshanm01/algorithm/quick_sort_simulation.html

Vous aimerez peut-être aussi