Você está na página 1de 15

Algoritmos e Programação

Adilson Barboza Lopes


QuickSort

Algorítmo mais eficiente para ordenação. Princípio: Divisão e Conquista


(Divide-and-Conquer).

O algoritmo, de maneira geral, é composto de 3 fases:

Divisão: divide-se os dados(vetor de elementos de entrada) em dois ou mais


subvetores disjuntos (separados);

Recursão: soluciona-se os problemas associados aos subvetores


recursivamente;

Conquista: obtém-se as soluções dos subproblemas e junta-se as mesmas em


uma única solução.
QuickSort (Características Gerais)

• Inicialmente, o vetor de elementos é particionado em três


segmentos S1, S2 e S3.

• S2 deverá conter apenas UM elemento denominada pivô.

• S1 deverá conter todos os elementos cujos valores são MENORES


ou IGUAIS ao pivô. Esse segmento está posicionado à esquerda de
S2.

• S3 deverá conter todos os elementos cujos valores são MAIORES do


que o pivô. Esse segmento está posicionado à direita de S2.
Exemplo Divisão e Conquista (QuickSort)

85 24 63 45 17 31 96 50 17 24 31 45 50 63 85 96

24 45 17 31 85 63 96 17 24 31 45 63 85 96

24 17 45 85 63 17 24 45 63 85

24 85 24 85

(a) Fase de Divisão (b) Fase de Conquista


QuickSort (Esquema)

Esquema conceitual do particionamento

Vetor Inicial : elementos[ 1 .. n ]


1 n

Vetor Particionado
1 k-1 k k+1 n

S1 S2 S3

onde: elementos [ i ]  elementos[ k ] , para i = 1, … , k - 1


elementos [ i ] > elementos [ k ] , para i = k + 1 , … , n
Princípio de Classificação/Ordenação
• O particionamento é reaplicado aos segmentos S1 e S3 e a todos os
segmentos correspondentes daí resultantes que tenham
quantidade de elementos MAIOR que 1.

• Quando não restarem segmentos a serem particionados, o vetor


estará ordenado.

• Perguntas:
– Qual é o pivô ideal ?
– Como escolher este pivô ?
QuickSort (Escolha do pivô)

O pivô ideal é aquele que produz segmentos S1 e S3 com tamanhos


(aproximadamente) iguais: pivô com valor mediano.
A identificação do pivô ideal requer a varredura de todo o vetor (o
benefício não justifica o custo).
Deseja-se um critério de escolha simples e rápido.
Sem conhecimento prévio sobre a distribuição de valores dos
elementos do vetor, supõe-se que qualquer uma possa ser o pivô e
arbitra-se, por exemplo, o primeiro elemento, ou o último, ou o do
meio.
Caso o vetor já se encontre parcialmente ordenado, pode-se
utilizar o elemento médio.
QuickSort (Procedimentos p/ Ordenação Crescente)

1) Escolha do pivô (p), por exemplo o primeiro elemento do vetor;


2) Processo de comparações:
Compara o segundo elemento, o terceiro elemento, ... até encontrar um
elemento[a]>pivô
Compara, a partir do final do vetor, os elementos n, n-1, ... Até encontrar
elemento[b]<=pivô.
3) Neste ponto, troca-se elemento[a] e elemento[b], e a busca
continua, para cima a partir de elemento[a+1], e para baixo, a partir
de elemento[b-1];
4) A busca termina quando os índices (a e b) se cruzarem. Neste
momento, a posição definitiva do pivô foi encontrada, e os valores de
pivô e elemento[b] são trocados;
5) O particionamento é realizado enquanto os segmentos resultantes
tiverem comprimento > 1.
QuickSort - Exemplo (1/6)

Vetor Original: [ 9 25 10 18 5 7 15 3 ]
pivô (p) = 9; a – indice de elemeto[2] = 25; b –indice de elemento[8] = 3

1 2 3 4 5 6 7 8
9 25 10 18 5 7 15 3 (25 > 9 ok!; 3 <= 9 ok!, troca)

9 3 10 18 5 7 15 25 (10>9 ok!;15<=9 não!,7<=9 ok!, troca)

9 3 7 18 5 10 15 25 (18 > 9 ok!; 5 <= 9 ok!, troca)

9 3 7 5 18 10 15 25 (18 > 9 ok!; 5 <= 9 ok!, cruzaram)

9 3 7 5 18 10 15 25 (troca o pivô com o elemento[b], b = 4)

5 3 7 9 18 10 15 25 (fim do primeiro nível de particionamento)


QuickSort - Exemplo (2/6)

Segmentos resultantes após 1º Particionamento:


1 2 3 4 5 6 7 8
[ 5 3 7 | 9 | 18 10 15 25 ]

1 2 3 4 5 6 7 8
[5 3 7] 9 [18 10 15 25]
QuickSort - Exemplo (3/6)

1 2 3

S1: [ 5 3 7 ]
pivô (p) <-5 ; a <- v[2] = 3 ; b = v[3] = 7

S1
1 2 3
5 3 7 (3>5 não!, 7>5 ok!; 7<=5 não!, 3 <=5 ok!, cruzaram)

5 3 7 (troca o pivô com o v[b], b = 2)

3 5 7 (fim, 2º nível de particionamento (S1))


QuickSort: Análise de Desempenho (1/2)

Melhor caso: particionamento produz


segmentos com mesmo tamanho.

Pior caso: Ocorrerá sempre que o vetor já estiver


ordenado ou em ordem inversa e escolhermos o
menor (ou maior) valor como particionador.
QuickSort

algoritmo "quicksort"
Var
i,j : inteiro
elementos : vetor[1..10] de inteiro

procedimento troca(a,b: inteiro)


var
t: inteiro
inicio
t<-elementos[a]
elementos[a]<-elementos[b]
elementos[b]<-t
fimprocedimento
QuickSort
funcao particao(ie,id : inteiro): inteiro
var
pivo, a, b : inteiro
inicio
pivo <- elementos[ie];
a <- ie+1
b <- id
enquanto (b > a) faca
enquanto (elementos[a] < pivo) e (a< b) faca
a <- a+1 //esquerda
fimenquanto
enquanto (elementos[b] > pivo) e (b >= a) faca
b <- b-1 //direita
fimenquanto
se b>=a entao
troca(a,b) // t<-elementos[a]; elementos[a]<-elemento[b];
fimse
fimenquanto
troca(ie,b)
retorne (b)
fimfuncao
QuickSort
procedimento quicksort(ie,id:inteiro)
var r : inteiro
inicio
se (id >ie) entao
r <- particao (ie,id)); /* importante * /
quicksort(ie,r-1)
quicksort(r+1,id)
fimse
fimprocedimento
Inicio
para i de 1 ate 10 faca
leia(elementos[i] )
fimpara
quicksort(1,10)
para i de 1 ate 10 faca
escreva(elementos[i])
fimpara
Fimalgoritmo

Você também pode gostar