0% acharam este documento útil (0 voto)
3 visualizações40 páginas

Complexidade do Algoritmo Quick Sort

O Quick Sort é um algoritmo de ordenação eficiente que utiliza a técnica de divisão e conquista, apresentando complexidade O(n log n) no melhor e caso médio, e O(n²) no pior caso. O algoritmo se baseia no particionamento de um vetor em subvetores e na ordenação recursiva desses subvetores. Estratégias de particionamento, como as de Hoare e Lomuto, são fundamentais para a eficiência do Quick Sort.

Enviado por

rafacien.rc
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
3 visualizações40 páginas

Complexidade do Algoritmo Quick Sort

O Quick Sort é um algoritmo de ordenação eficiente que utiliza a técnica de divisão e conquista, apresentando complexidade O(n log n) no melhor e caso médio, e O(n²) no pior caso. O algoritmo se baseia no particionamento de um vetor em subvetores e na ordenação recursiva desses subvetores. Estratégias de particionamento, como as de Hoare e Lomuto, são fundamentais para a eficiência do Quick Sort.

Enviado por

rafacien.rc
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

PGINF591 – Algoritmos e Estruturas de Dados

Quick Sort

Prof. Dr. Rafael Giusti


rgiusti@[Link]
Apresentação

» O Quick Sort é um algoritmo de ordenação


baseado em divisão e conquista
» Possui complexidade temporal O(n logn) no
melhor caso e no caso médio
» E complexidade temporal O(n²) no pior caso
» Possui complexidade espacial O(log n) e O(n)
no melhor e no pior casos
» Embora seja quadrático no pior caso, o Quick
Sort é um algoritmo de ordenação com bastante
aplicação prática
Intuição

» Dado um vetor A com tamanho n, o Quick Sort


realiza os seguintes passos
» Divisão
~ Particiona o vetor A em dois subvetores, Ae e
Ad, tais que nenhum elemento de Ae é maior do
que os elementos em Ad e vice-versa
~ Ordena recursivamente Ae
~ Ordena recursivamente Ad
» Conquista
~ Concatena os vetores ordenados Ae e Ad
Intuição
1. Particionamento: os
7 3 6 4 1 2 5 elementos do vetor são
rearranjados em dois sub-
vetores

2 3 1 4 6 7 5
Intuição
1. Particionamento: os
7 3 6 4 1 2 5 elementos do vetor são
rearranjados em dois sub-
vetores

Ae → nenhum elemento maior que 4


2. Ordenação:
12 23 31 4 65 76 57
Ordena Ae recursivamente
Ad → nenhum elemento menor que 4 Ordena Ad recursivamente

3. Conquista: os vetores Ae e
Ad são concatenados
(desnecessário em Python
porque as listas são referências
compartilhadas na recursão)
Algoritmo de particionamento

» O ponto mais importante é o particionamento


» Precisamos de uma estratégia (algoritmo) de
particionamento apropriada (eficiente)
» Essa estratégia deve escolher um pivô e um
ponto de corte
» Um “ponto de sustentação”
» Os elementos à esquerda do ponto de corte
não são maiores que o pivô
» Os elementos à direita não são menores
Algoritmo de particionamento

» O algoritmo de particionamento deve ser


eficiente e também eficaz
» Deve tentar encontrar um ponto de corte tão
próximo do índice central quanto possível
» Deve fazer o menor número de trocas possível

» Duas estratégias relevantes


» Particionamento de Hoare
» Particionamento de Lomuto
Particionamento de Hoare

» Escolhe o valor do elemento central como pivô


» Percorre o vetor com dois índices
» i: o primeiro elemento mais à esquerda que
não é menor do que o pivô
» j: o primeiro elemento mais à direita que não é
maior do que o pivô

2 6 3 4 7 5 1
Particionamento de Hoare

» Escolhe o valor do elemento central como pivô


» Percorre o vetor com dois índices
» i: o primeiro elemento mais à esquerda que
não é menor do que o pivô
» j: o primeiro elemento mais à direita que não é
maior do que o pivô
pivô

2 6 3 4 7 5 1
Particionamento de Hoare

» Escolhe o valor do elemento central como pivô


» Percorre o vetor com dois índices
» i: o primeiro elemento mais à esquerda que
não é menor do que o pivô
» j: o primeiro elemento mais à direita que não é
maior do que o pivô
pivô

2 6 3 4 7 5 1

i
Particionamento de Hoare

» Escolhe o valor do elemento central como pivô


» Percorre o vetor com dois índices
» i: o primeiro elemento mais à esquerda que
não é menor do que o pivô
» j: o primeiro elemento mais à direita que não é
maior do que o pivô
pivô

2 61 3 4 7 5 16

i j

Esses elementos estão do lado errado do pivô… então vamos trocá-los.


Particionamento de Hoare

» Escolhe o valor do elemento central como pivô


» Percorre o vetor com dois índices
» A forma como o vetor é percorrido é importante
» i: começa em 0 (ou -1) e incrementa até
encontrar o elemento fora de posição
» j: começa em n + 1 (ou n) e decrementa até
encontrar o elemento fora de posição
» O particionamento termina quando i ≥ j
» O ponto de corte será o índice j
Particionamento de Hoare

j=8

3 6 5 4 1 7 2

i=0

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=8

pivô
3 6 5 4 1 7 2

i=0

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=8

pivô
3 6 5 4 1 7 2

i=1

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=8

pivô
3 6 5 4 1 7 2

i=2

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=7

pivô
3 62 5 4 1 7 26

i=2

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=7

pivô
3 2 5 4 1 7 6

i=3

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=6

pivô
3 2 5 4 1 7 6

i=3

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=5

pivô
3 2 15 4 51 7 6

i=3

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=5

pivô
3 2 1 4 5 7 6

i=4

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=4

pivô
3 2 1 4 5 7 6

i=4

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4 j=4

pivô
3 2 1 4 5 7 6

j = 4 é o ponto de corte
i=4

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

4
pivô
3 2 1 4 5 7 6

j = 4 é o ponto de corte

Cheatsheet:
Variável i: começa em zero e incrementa até encontrar um valor que
não é menor do que o pivô
Variável j: começa em n + 1 e decrementa até encontrarmos um
valor não é maior do que o pivô

Troca:
Se i < j, então os elementos A[i] e A[j] são trocados

Término:
Quando i ≥j, o índice j será o ponto de corte
Particionamento de Hoare

E na metade direita
também
4
pivô
3 2 1 4 5 7 6

j = 4 é o ponto de corte
QuickSort na metade
esquerda!
Particionamento de Hoare

» Algoritmo Hoare(A)

meio ← ⌈|A|/2⌉, pivô ← A[meio]

i ← 0, j ← |A| + 1

repita incondicionalmente

faça i ← i + 1 enquanto A[i] < pivô

faça j ← j - 1 enquanto A[j] > pivô

se i < j

troque A[i] ↔ A[j]

senão

retorne j
Ordenação com QuickSort e particionamento de Hoare

» Algoritmo QuickSort(A)

se |A| > 1

pontoCorte ← Hoare(A)

esq ← QuickSort(A[1..pontoCorte])

dir ← QuickSort(A[pontoCorte+1..|A|])

A ← concatena(esq, dir)

retorna A
Complexidade do Quick Sort

» O melhor caso acontece quando o ponto de corte


sempre termina no meio do vetor

8 2 1 4 5 7 3
Complexidade do Quick Sort

» O melhor caso acontece quando o ponto de corte


sempre termina no meio do vetor

8 2 1 4 5 7 3

3 2 1 4 5 7 8
Complexidade do Quick Sort

» O melhor caso acontece quando o ponto de corte


sempre termina no meio do vetor

8 2 1 4 5 7 3

3 2 1 4 5 7 8

1 2 3 4
Complexidade do Quick Sort

» O melhor caso acontece quando o ponto de corte


sempre termina no meio do vetor

8 2 1 4 5 7 3

3 2 1 4 5 7 8

1 2 3 4

1 2
Complexidade do Quick Sort

» O melhor caso acontece quando o ponto de corte


sempre termina no meio do vetor

8 2 1 4 5 7 3

3 2 1 4 5 7 8

1 2 3 4

1 2 3 4
Complexidade do Quick Sort

» O melhor caso acontece quando o ponto de corte


sempre termina no meio do vetor

8 2 1 4 5 7 3

3 2 1 4 5 7 8

1 2 3 4 5 7 8

1 2 3 4
Complexidade do Quick Sort

» O melhor caso acontece quando o ponto de corte


sempre termina no meio do vetor

8 2 1 4 5 7 3

3 2 1 4 5 7 8

1 2 3 4 5 7 8

1 2 3 4 7 8
Complexidade do Quick Sort

» O pior caso acontece quando o ponto de corte


sempre termina no primeiro ou no último índice

8 7 3 1 5 6 2
Complexidade do Quick Sort

» O pior caso acontece quando o ponto de corte


sempre termina no primeiro ou no último índice

8 7 3 1 5 6 2

1 7 3 8 5 6 2
Complexidade do Quick Sort

» O pior caso acontece quando o ponto de corte


sempre termina no primeiro ou no último índice

8 7 3 1 5 6 2

1 7 3 8 5 6 2

7 3 2 5 6 8
Complexidade do Quick Sort

» O pior caso acontece quando o ponto de corte


sempre termina no primeiro ou no último índice

8 7 3 1 5 6 2

1 7 3 8 5 6 2

7 3 2 5 6 8

2 3 7 5 6
Complexidade do Quick Sort

» O pior caso acontece quando o ponto de corte


sempre termina no primeiro ou no último índice

8 7 3 1 5 6 2

1 7 3 8 5 6 2

7 3 2 5 6 8

2 3 7 5 6
Complexidade do Quick Sort

» QuickSort: melhor caso e pior caso


» No melhor caso, a entrada é divida em dois sub-
-problemas de tamanhos [quase] iguais
» No pior caso, a entrada é divida em um sub-problema
com tamanho 1 e um sub-problema com tamanho n-1
» Para fazer:
» Monte a relação de recorrência do QuickSort no melhor
e no pior casos
» Analise, pelo método da árvore, as complexidades

Você também pode gostar