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

06-Merge Sort

O documento discute o algoritmo de ordenação por intercalação, conhecido como Merge Sort, que utiliza o paradigma de divisão e conquista. Ele detalha como o vetor é dividido em metades, cada uma ordenada separadamente, e depois intercaladas para formar a lista ordenada final. A complexidade do Merge Sort é apresentada como mais eficiente em comparação com algoritmos quadráticos tradicionais, como o método da bolha.

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)
18 visualizações74 páginas

06-Merge Sort

O documento discute o algoritmo de ordenação por intercalação, conhecido como Merge Sort, que utiliza o paradigma de divisão e conquista. Ele detalha como o vetor é dividido em metades, cada uma ordenada separadamente, e depois intercaladas para formar a lista ordenada final. A complexidade do Merge Sort é apresentada como mais eficiente em comparação com algoritmos quadráticos tradicionais, como o método da bolha.

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

Ordenação por Intercalação


(Merge Sort)

Prof. Dr. Rafael Giusti


[email protected]
Divisão e conquista

» Divisão e conquista é um paradigma de projeto


» Algoritmos de divisão e conquista compartilham
as seguintes características
» A entrada é (normalmente) dividida em dois
sub-problemas de tamanhos aproxim. iguais
» Cada sub-problema é resolvido separadamente
» A solução dos sub-problemas é juntada para
construir a solução da entrada original
Por que dividir?

» Ordenação quadrática vs. quasilinear


» Os algoritmos de ordenação que estudamos
até agora são quadráticos
~ Bolha método de força bruta
~ Inserção redução e conquista
~ Seleção força bruta
» Todos eles fazem comparação entre elementos
adjacentes ou entre um elemento e os demais
do vetor
Por que dividir?

» Métodos da bolha e da inserção: comparam apenas


elementos adjacentes

7 8 5 3 6 2 4 1
j=1 i=n

» Método da seleção: compara um elemento contra


todos os restantes do vetor
i=1 j=4

3 2 3 2 2 1 5

menor
Método da bolha é pouco eficiente: change my mind...

» Esses algoritmos são pouco eficientes porque ganham


pouca informação sobre os dados em cada passo
» Após a primeira passagem pelo vetor...

7 8 5 3 6 2 4 1
j=1 i=n
Método da bolha é pouco eficiente: change my mind...

» Esses algoritmos são pouco eficientes porque ganham


pouca informação sobre os dados em cada passo
» Após a primeira passagem pelo vetor...

7 8
5 8
5 3 6 2 4 1
j=2 i=n
Método da bolha é pouco eficiente: change my mind...

» Esses algoritmos são pouco eficientes porque ganham


pouca informação sobre os dados em cada passo
» Após a primeira passagem pelo vetor...

7 5 8
3 8
3 6 2 4 1
j=3 i=n
Método da bolha é pouco eficiente: change my mind...

» Esses algoritmos são pouco eficientes porque ganham


pouca informação sobre os dados em cada passo
» Após a primeira passagem pelo vetor...

7 5 3 8
6 6
8 2 4 1
j=4 i=n
Método da bolha é pouco eficiente: change my mind...

» Esses algoritmos são pouco eficientes porque ganham


pouca informação sobre os dados em cada passo
» Após a primeira passagem pelo vetor...

7 5 3 6 2
8 8
2 4 1
j=5 i=n
Método da bolha é pouco eficiente: change my mind...

» Esses algoritmos são pouco eficientes porque ganham


pouca informação sobre os dados em cada passo
» Após a primeira passagem pelo vetor...

7 5 3 6 2 8
4 8
4 1
j=6 i=n
Método da bolha é pouco eficiente: change my mind...

» Esses algoritmos são pouco eficientes porque ganham


pouca informação sobre os dados em cada passo
» Após a primeira passagem pelo vetor...

7 5 3 6 2 4 81 81
j=7 i=n
Método da bolha é pouco eficiente: change my mind...

» Esses algoritmos são pouco eficientes porque ganham


pouca informação sobre os dados em cada passo
» Após a primeira passagem pelo vetor…
...tudo o que descobrimos é que o elemento no índice
A[n] é maior que todos os demais

7 5 3 6 2 4 1 8
i=n

Em nenhum momento tentamos estabelecer relações


entre coleções de elementos. Precisamos verificar
todos os pares pelo menos uma vez
Um algoritmo um pouco melhor: o Professor Sort

» Um algoritmo “quase” de divisão e conquista


» Professor Sort
~ Divida o vetor em dois
~ Aplique o método da bolha em cada metade
separadamente
~ Faça intercalação das duas metades...
Um algoritmo um pouco melhor: o Professor Sort

» À primeira vista, esse algoritmo não parece ser mais


eficiente do que o método da bolha…
» Suponha que o tempo necessário para ordenar um
vetor de 100.000 elementos é de 400 segundos…

100.000 elementos 400s

» Ao dividirmos o vetor em 2…

50.000 elementos 200s 50.000 elementos 200s

O tempo total não continua sendo o mesmo? Isto é, 200 segundos +


200 segundo = 400 segundos?
Um algoritmo um pouco melhor: o Professor Sort

» À primeira vista, esse algoritmo não parece ser mais


eficiente do que o método da bolha…
» Suponha que o tempo necessário para ordenar um
vetor de 100.000 elementos é de 400 segundos…

100.000 elementos 400s

» Ao dividirmos o vetor em 2…

50.000 elementos 200s


100s 50.000 elementos 200s
100s

O tempo total não continua sendo o mesmo? Isto é, 200 segundos +


200 segundo = 400 segundos? Não. O certo seria 100s em
cada metade e um total de aprox. 200s
Por que funciona?

» Considerando-se que o método da bolha é Θ(n²),


podemos estimar a complexidade do ProfessorSort
como sendo a seguinte

Algoritmo
Algoritmo ProfessorSort(A)
ProfessorSort(A)
Ae
Ae ←← metade
metade esquerda de AA ΘΘ(1)
esquerda de (1)

Ad
Ad ←← metade
metade direita
direita de
de AA Θ
Θ(1)
(1)

BubbleSort(Ae)
BubbleSort(Ae) Θ
Θ((((n/2)²
n/2)²))
BubbleSort(Ad)
BubbleSort(Ad) Θ
Θ((((n/2)²
n/2)²))

AA ←← intercale
intercale Ae Ad ΘΘ((n)n)
Ae ++ Ad
Por que funciona?

» Considerando-se que o método da bolha é Θ(n²),


podemos estimar a complexidade do ProfessorSort
como sendo a seguinte

Algoritmo
Algoritmo ProfessorSort(A)
ProfessorSort(A)
Ae
Ae ←← metade
metade esquerda de AA ΘΘ(1)
esquerda de (1)

Ad
Ad ←← metade
metade direita
direita de
de AA Θ
Θ(1)
(1)

BubbleSort
BubbleSort(Ae)
(Ae) Θ
Θ((n²/4)
n²/4)
BubbleSort
BubbleSort(Ad)
(Ad) Θ
Θ((n²/4)
n²/4)

AA ←← intercale
intercale Ae Ad ΘΘ((n)n)
Ae ++ Ad
Por que funciona?

» Considerando-se que o método da bolha é Θ(n²),


podemos estimar a complexidade do ProfessorSort
como sendo a seguinte
Algoritmo
Algoritmo ProfessorSort(A)
ProfessorSort(A)
Ae
Ae ←← metade
metade esquerda
esquerda de
de AA
Ad
Ad ←← metade
metade direita
direita de
de AA

BubbleSort
BubbleSort(Ae)
(Ae)
BubbleSort
BubbleSort(Ad)
(Ad)

AA ←← intercale
intercale Ae
Ae ++ Ad
Ad

Θ
Θ(1)
(1) + Θ
Θ(1)
(1) + Θ
Θ((n²/4)
n²/4) + Θ
Θ((n²/4)
n²/4) + Θ
Θ((n)
n) = Θ
Θ((n²/2)
n²/2)
Bolha vs. professor
Bolha vs. professor

» O algoritmo “ProfessorSort” é quadrático, assim como


o método da bolha
» Ambos têm pior caso Θ(n²)
» Mas o “ProfessorSort” leva aproximadamente um
quarto do tempo utilizado pelo método da bolha
» Como o método da bolha é quadrático, reduzir o
tamanho do vetor pela metade “corta” o tempo
necessário para ordenar cada metade em 75%

E se continuarmos dividindo o
vetor ao meio até que sobre
apenas um elemento????
Merge Sort

» A ordenação pelo Método da Intercalação (também


chamado Merge Sort) é um método de divisão e
conquista que faz dois passos:
» Divisão:
~ O vetor, de tamanho n, é dividido em duas metades
com tamanhos ⌊n/2⌋ e ⌈n/2⌉
~ Cada metade é ordenada separadamente
» Conquista:
~ As duas metades ordenadas são intercaladas,
produzindo a ordenação do vetor original
Merge Sort

Divisão

5 3 6 2 7 4 1
Merge Sort

Divisão

5 3 6 2 7 4 1
Merge Sort

Caso base

5 3 6 2 7 4 1
Merge Sort

Divisão

5 3 6 2 7 4 1
Merge Sort

Caso base

5 3 6 2 7 4 1
Merge Sort

Caso base Caso base

5 3 6 2 7 4 1
Merge Sort

Conquista

5 3 6 2 7 4 1

3 6
Vetor auxiliar para intercalação
Merge Sort

Conquista

5 3 6 2 7 4 1

3 6
Vetor auxiliar para intercalação
Merge Sort

Conquista

5 3 6 2 7 4 1

3 5 6
Vetor auxiliar para intercalação
Merge Sort

Conquista

3 5 6 2 7 4 1

3 5 6
Vetor auxiliar para intercalação
Merge Sort

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Divisão

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Divisão

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Caso base

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Caso base

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Caso base Caso base

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Caso base Caso base

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Conquista

3 5 6 2 7 4 1

2 7
Vetor auxiliar para intercalação
Merge Sort

Divisão

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Caso base

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Caso base Caso base

3 5 6 2 7 4 1

Vetor auxiliar para intercalação


Merge Sort

Conquista

3 5 6 2 7 4 1

1 4
Vetor auxiliar para intercalação
Merge Sort

Conquista

3 5 6 2 7 1 4

1 4
Vetor auxiliar para intercalação
Merge Sort

Conquista

3 5 6 2 7 1 4

1 2 4 7
Vetor auxiliar para intercalação
Merge Sort

Conquista

3 5 6 1 2 4 7

1 2 4 7
Vetor auxiliar para intercalação
Merge Sort

3 5 6 1 2 4 7

Vetor auxiliar para intercalação


Merge Sort

Conquista

3 5 6 1 2 4 7

1 2 3 4 5 6 7
Vetor auxiliar para intercalação
Merge Sort

Conquista

1 2 3 4 5 6 7

1 2 3 4 5 6 7
Vetor auxiliar para intercalação
Merge Sort

1 2 3 4 5 6 7

Vetor auxiliar para intercalação


Merge sort

» Algoritmo MergeSort(A)
se |A| ≥ 2
meio ← ⌊|A|/2⌋

esq ← MergeSort(A[1..meio])
dir ← MergeSort(A[meio+1..|A|])
A ← intercala(esq, dir)
retorne A
Complexidade do MergeSort

» O Merge Sort é um algoritmo recursivo

Algoritmo
Algoritmo MergeSort(A)
MergeSort(A)
se
se |A|
|A| ≥≥ 22
meio
meio ←← ⌊⌊|A|//22⌋⌋
|A|

esq
esq ←← MergeSort(A[1..meio])
MergeSort(A[1..meio])
dir
dir ←← MergeSort(A[meio+1..|A|])
MergeSort(A[meio+1..|A|])
AA ←← intercala(esq,
intercala(esq, dir)
dir)
retorne
retorne AA

» Seja n = |A| o tamanho da entrada


» Então como descrever o tempo do algoritmo por
meio de uma função T(n)?
Relação de recorrência

» O tempo de um algoritmo recursivo pode ser descrito


na forma de uma relação de recorrência

Algoritmo
Algoritmo fatorial(n)
fatorial(n)
se
se nn ≤≤ 11
retorne
retorne 11
senão
senão
retorne
retorne nn ** fatorial(n
fatorial(n -- 1)
1)

» Passos necessários para n = 1?


» T(1) =
» Passos necessários para n > 1? (ex.: n = 5)
» T(5) =
Relação de recorrência

» O tempo de um algoritmo recursivo pode ser descrito


na forma de uma relação de recorrência
Quando
Quandonn==1...
1...

Algoritmo
Algoritmo fatorial(n)
fatorial(n)
se
se nn ≤≤ 11 ...estas
...estasduas
duaslinhas
linhassão
são
retorne
retorne 11 executadas
executadasumaumavez
vezcada.
cada.
senão
senão
retorne
retorne nn ** fatorial(n
fatorial(n -- 1) 1)

» Passos necessários para n = 1?


» T(1) = 2
» Passos necessários para n > 1? (ex.: n = 5)
» T(5) =
Relação de recorrência

» O tempo de um algoritmo recursivo pode ser descrito


na forma de uma relação de recorrência
Quando
Quandonn==5...
5...

Algoritmo
Algoritmo fatorial(n)
fatorial(n)
se
se nn ≤≤ 11
...estas
...estasduas
duaslinhas
linhas
executadas retorne
retorne 11
executadasumaumavez
vez
cada...
cada... senão
senão
retorne
retorne nn ** fatorial(n
fatorial(n -- 1)
1)

…e
…e esta
estalinha
linha executa
executa 11vez.
vez.Além
Alémdisso,
disso,precisamos
precisamos contar
contar
» Passos necessários também
para
tambémtodo
n = 1?
todoootempo
temponecessário
necessáriopara
paraoocalculo
calculode
de
fatorial(4),
fatorial(4),que
queééT(4)...
T(4)...
» T(1) = 2
» Passos necessários para n > 1? (ex.: n = 5)
» T(5) = 3 + T(4) Então
EntãoT(5)
T(5)ééootempo
tempogasto
gastona
nachamada
chamada
fatorial(5)
fatorial(5)++ootempo
tempogasto
gastocom
comfatorial(4)
fatorial(4)
Relação de recorrência

» O tempo de um algoritmo recursivo pode ser descrito


na forma de uma relação de recorrência

Algoritmo
Algoritmo fatorial(n)
fatorial(n)
se
se nn ≤≤ 11
retorne
retorne 11
senão
senão
retorne
retorne nn ** fatorial(n
fatorial(n -- 1)
1)

» Como uma relação de recorrência

Extrapolando
Extrapolandopara
paraqualquer
qualquervalor
valorde
den...
n...
Relação de recorrência

» O tempo de um algoritmo recursivo pode ser descrito


na forma de uma relação de recorrência

Algoritmo
Algoritmo fatorial(n)
fatorial(n)
se
se nn ≤≤ 11
retorne
retorne 11
senão
senão
retorne
retorne nn ** fatorial(n
fatorial(n -- 1)
1)

» Como uma relação de recorrência

Observe
Observeque
queos
osvalores
valoresexatos
exatosdas
dasconstantes
constantesnão
não
são
sãoimportantes…
importantes…podemos
podemostrocar
trocar“2”
“2”ee“3”
“3”por
porcc
Relação de recorrência

» O tempo de um algoritmo recursivo pode ser descrito


na forma de uma relação de recorrência

Algoritmo
Algoritmo fatorial(n)
fatorial(n)
se
se nn ≤≤ 11
retorne
retorne 11
senão
senão
retorne
retorne nn ** fatorial(n
fatorial(n -- 1)
1)

» Como uma relação de recorrência


Tempo do Merge Sort

» Qual T(n) para o Merge Sort?

Algoritmo
Algoritmo MergeSort(A)
MergeSort(A)
se
se |A|
|A| ≥≥ 22
meio
meio ←← ⌊⌊|A|//22⌋⌋
|A|

esq
esq ←← MergeSort(A[1..meio])
MergeSort(A[1..meio])
dir
dir ←← MergeSort(A[meio+1..|A|])
MergeSort(A[meio+1..|A|])
AA ←← intercala(esq,
intercala(esq, dir)
dir)
retorne
retorne AA

» Quando n = 1 (caso base)…


» T(1) =
» Quando n > 1…
» T(n) =
Tempo do Merge Sort

» Qual T(n) para o Merge Sort?

Algoritmo
Algoritmo MergeSort(A)
MergeSort(A)
se
se |A|
|A| ≥≥ 22
meio
meio ←← ⌊⌊|A|//22⌋⌋
|A|

esq
esq ←← MergeSort(A[1..meio])
MergeSort(A[1..meio])
dir
dir ←← MergeSort(A[meio+1..|A|])
MergeSort(A[meio+1..|A|])
AA ←← intercala(esq,
intercala(esq, dir)
dir)
retorne
retorne AA
Tempo do Merge Sort

» Como encontrar uma fórmula fechada em notação O


para a relação de recorrência?

» Existem três técnicas


» Método da substituição
» Método da árvore
» Teorema Mestre
Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = ?

T(4)
Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = 4c + T(2)
2T(4/2)
2T(2)+ T(2)

T(4)
Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = 4c + T(2) + T(2)

T(4)

T(2) T(2)
Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = 4c + T(2) + T(2)

T(4)
4c

T(2) T(2)
Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = 4c + T(2) + T(2)
T(2) = 2c + T(1) + T(1)

4c

T(2) T(2)
Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = 4c + 2c + T(1) + T(1) + 2c + T(1) + T(1)
T(2) = 2c + T(1) + T(1)

4c

T(2) T(2)
Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = 4c + 2c + T(1) + T(1) + 2c + T(1) + T(1)
T(2)

4c

T(2) T(2)

T(1) T(1) T(1) T(1)


Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = 4c + 2c + T(1) + T(1) + 2c + T(1) + T(1)
T(2)

4c

T(2)
2c T(2)
2c

T(1) T(1) T(1) T(1)


Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = 4c + 2c + T(1)
c + T(1)
c + 2c + T(1)
T(2) c + T(1)
c
T(1) = c

4c

T(2)
2c T(2)
2c

T(1) T(1) T(1) T(1)


Método da árvore

» Podemos expandir a relação e representar os termos


em uma árvore...
Exemplo T(4) = 4c + 4c
2c + 4c
c2c
+c +c c+++T(1)
T(1) c c+
c +c+c +
2cc+ T(1)
T(2) c + T(1)
c

4c

T(2)
2c T(2)
2c

T(1)
c T(1)
c T(1)
c T(1)
c
Método da árvore

cn cn

cn/2 cn/2 cn/2 + cn/2


cn

log2(n) níveis
cn/4 cn/4 cn/4 cn/4 cn + cn/4 + cn/4 + cn/4
cn/4
× cn (soma dos nós
em cada nível)

T(n) = cn×log2(n)

T(n) = O(n logn)

c c c c c c c c ... c c+c+c+c+c+c+…+c
cn
Complexidade do Merge Sort

» Complexidade temporal
» O(n logn)

» Complexidade espacial (vetor auxiliar para


intercalação)
» O(n)
C’est fini!

Você também pode gostar