Uma das razões dele ser rápido é porque a análise começa das duas pontas e vai em direção ao centro, onde geralmente está localizado o elemento pivô. Depois de analisar e mover todos os elementos em relação ao pivô, então divide-se o vetor em duas partes e aplica a mesma técnica nos dois subvetores, até que não seja possível dividir os vetores.
Por aplicar a mesma técnica diversas vezes, vamos fazer uso da recursividade, e por esse motivo, separamos o algoritmo em uma função própria, como o pseudocódigo abaixo mostra:
01. QuickSort(vet:INTEIRO[],inicio:INTEIRO, fim:INTEIRO):NEUTRO
02. INICIO
03. var i,j,pivo,aux: INTEIRO
04. i=inicio
05. j=fim
06. pivo=(inicio+fim) DIV 2
07. ENQUANTO (i<j) FACA
08. ENQUANTO (vet[i]<vet[pivo]) FACA
09. i++
10. FIMENQUANTO
11. ENQUANTO (vet[j]>vet[pivo]) FACA
12. j--
13. FIMENQUANTO
14. SE (i<=j) ENTAO
15. aux = vet[i]
16. vet[i] = vet[j]
17. vet[j] = aux
18. i++
19. j--
20. FIMSE
21. FIMENQUANTO
22. SE(j>inicio) ENTAO
23. QuickSort(vet,inicio,j)
24. FIMSE
25. SE(i<fim) ENTAO
26. QuickSort(vet,i,fim)
27. FIMSE
28. FIM
29.
30. PRINCIPAL():NEUTRO
31. INICIO
32. var vet = {55, 76, 26, 64, 26, 80, 71, 46}
33. QuickSort(vet,0,vet.tamanho-1)
34. FIM
Vamos ver como funciona, usando o mesmo vetor que usamos para os outros algoritmos:
Primeiro, invocamos a função que vai abranger todo o vetor, ou seja, da posição 0 até 7:
Depois atribuimos as variáveis de controle i e j para marcar o inicio e o final do vetor
Em seguida, elegemos o elemento pivô, que geralmente fica no ponto médio. Para achar, pegamos o valor do inicio e do final da parte que estamos vendo, ou seja, 0 e 7. Somamos os dois e dividimos por dois que resultará um quociente 3. Esse elemento será o nosso pivô nesse momento.
Agora começaremos a análise e as trocas até que i e j se encontrem. Como queremos que o vetor fique em ordem crescente, todos os números menores que o pivô devem ficar a sua esquerda e os maiores a sua direita. Então, iniciaremos a busca do i para o primeiro número que seja maior ou igual ao pivo:
Se o primeiro número não foi maior nem igual, verifique o próximo e vai verificando até
encontrar:
Depois que achou um número maior que o pivô para a variável i, agora procuramos um valor menor ou igual ao pivô para a variável j:
Uma vez encontrado ambos valores para i e para j, vamos realizar a troca entre eles da mesma forma que foi feito no Bubble Sort e Selection Sort.
Com ambos valores trocados, tanto o i quanto o j avançam uma posição ao centro.
Agora, continuaremos com a busca de um número que seja maior ou igual que o pivô para a variável i:
O motivo de que um valor igual ao pivô é justamente esse caso, se existir um número menor a direita do pivô, o pivô precisará ser trocado por um número menor. Entretanto, isso não afetará a ordenação caso depois de um novo pivô seja escolhido, um número maior que ele a esquerda já exista. Agora que a nova posição de i foi escolhida, vamos localizar a nova posição de j.
Localizado ambos os valores e as variáveis i e j ainda não se cruzaram, então realiza-se a troca (a imagem vai ser simplicada, mas segue o mesmo esquema de trocas anteriores):
E depois da troca, ambos i e j avaçam uma posição:
As variáveis i e j acabaram de se cruzar, então agora o vetor será dividido em dois, um subvetor que vai de 0 até j, que no caso é 3, e o outro que vai de i (4) até o final (7).
Note que o maior número do primeiro subvetor não é maior que o menor número do segundo subvetor, ou seja, não tem números que precisam ser trocado de posição entre os dois subvetores. Agora, aplicamos o mesmo algoritmo para o primeiro subvetor, definindo seu i, j e pivô:
Encontrado os valores, vamos iniciar o processo de procura:
Nesse caso, encontramos de primeira os valores que queríamos. Como i e j não cruzaram, fazemos a troca:
Depois da troca, tanto o i quanto o j avançam uma posição:
Encontrado o próximo número, fazemos a troca e em seguida i e j avançam:
Como i e j se cruzaram, dividimos novamente o subvetor em duas partes, uma do início até o j e outra do i até o final do subvetor:
Apesar desse caso, o primeiro subvetor já estar ordenado, haverá casos em que não estará exato, por isso que é subdividido. Então, é aplicado novamente o algoritmo de Quick Sort para o subvetor [0,1].
Nesse caso, depois de definido o i e j e o pivô é analisado os números. Nesse caso, ambos os números são iguais ao pivô, então haverá uma troca simbólica e i e j avançarão uma posição:
Agora, i e j cruzaram, ou seja a busca acabou. Normalmente agora seria a subdivisão do vetor, mas note que j está no início e o i está no final. Quando isso ocorre, significa que a ordenação daquele subvetor está finalizada, não havendo necessidade de subdividir. Agora o algoritmo vai processar o subvetor [2,3]:
Agora procuraremos os valores para i e j no subvetor. A variável i vai permanecer no local, uma vez que 46 é igual a 46. Enquanto isso, j avançará uma casa, uma vez que 55 não é menor que 46 e parará também na posição 2.
Nesse caso, o algoritmo tentará trocar, mas sem efeito, já que as posições i e j são as mesmas. então i e j avançarão uma casa, fazendo os dois cruzarem.
Nesse caso, j já ultrapassou o início e o i está no final, indicando que a ordenação dessa parte está finalizada.
Agora, ambos os lados do subvetor[0,3] estão ordenado, assim, o próprio subvetor [0,3] também está concluído:
E agora, o processo se repete para o outro lado do vetor:
Aqui ocorreu algo diferente, a variável i chegou no final, mas o j não. Isso significa que aqui vai acontecer uma divisão, mas uma delas não será necessário analisar. Com isso, só será necessário criar apenas 1 subvetor, aquele que vai do início até o j (vetor[4,6]).
E agora repete o processo:
Aqui, j e i cruzaram antes de j chegar ao inicio, que significa que o vetor será dividido novamente:
O algoritmo novamente se aplica nesse subvetor (i=4, j=5 e pivo=4), entretanto nada ocorrerá já que o subvetor já está ordenado. Com isso, o vetor[4,5] é concluído, e por consequência o vetor[4,6] e o vetor [4,7] e fechando o algoritmo para ordenação do vetor principal.
nossa, muito obrigado mesmo.. me ajudou demais
ResponderExcluirtu é o mais pika carai
VlW man muito bom, ajudou demais.
ResponderExcluir