Estruturas de Dados 2 - DAINF

Propaganda
Estruturas de Dados 2
Técnicas de Projeto de Algoritmos
Dividir e Conquistar
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 1/83
Dividir e Conquistar
●
Projeto de Algoritmos por Divisão e Conquista
●
Introdução
●
Busca “Recursiva”
●
Ordenação: InsertionSort, MergeSort, HeapSort e
QuickSort
●
Resumo
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 2/83
Dividir e Conquistar
●
Introdução
●
“Dividir e Conquistar” é uma técnica de projeto de
algoritmos que consiste em resolver um problema a
partir da solução de “sub-problemas menores” do
mesmo tipo.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 3/83
Dividir e Conquistar
●
Introdução
●
“Dividir e Conquistar” é uma técnica de projeto de
algoritmos que consiste em resolver um problema a
partir da solução de “sub-problemas menores” do
mesmo tipo.
●
Se os sub-problemas obtidos após a “divisão” ainda
são muito grandes para a solução “direta”, aplica-se
novamente a “divisão”, até ter problemas pequenos o
suficiente para terem solução trivial ou direta.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 4/83
Dividir e Conquistar
●
Introdução
●
Após o processo de “divisão” em sub-problemas
menores, e sua “conquista”, basta “combinar” os
resultados dos sub-problemas menores, para obter a
solução para o problema como um todo.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 5/83
Dividir e Conquistar
Passos para “divisão e conquista”:
1. Divisão: propor uma forma de dividir o problema
original em sub-problemas iguais, porém menores
(recursivamente);
2. Conquista: ao se obter sub-problemas “pequenos o
suficiente”, resolvê-los diretamente;
3. Combinação: combinar as soluções de forma a obter
a solução ao problema original.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 6/83
Dividir e Conquistar
●
Vantagens
●
Solução “direta” do ponto de vista da recursividade;
●
Elegância;
●
Usualmente produz algoritmos eficientes
(complexidade logarítmica!!!)
●
Desvantagem
●
Recursão!!!!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 7/83
Dividir e Conquistar
●
Como aplicar?
●
Processo “Indutivo” ao projeto de algoritmos(recursão)
●
Aplicável sempre que for possível obter “subproblemas menores independentes entre si”
●
Procurar uma divisão “igualitária” de um problema em
diversos sub-problemas.......
●
Deve ser possível (e de preferência simples e rápido)
combinar os resultados dos sub-problemas....
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 8/83
Dividir e Conquistar
●
Justificativa
●
Esta técnica pode ser empregada em diversas
situações comuns porém importantes:
●
Somar N números;
●
Encontrar um elemento em um vetor ordenado;
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 9/83
Dividir e Conquistar
●
Exemplo da aplicação da técnica:
●
Como somar N números, a1, a2, ..., an?
Se n é 1, a soma é o próprio a1.
● Se n>1, podemos dividir o problema em dois subproblemas menores:
1.Somar os números de a1 até an/2 ;
●
2.Somar os número de an/2 até an ;
3.Somar os resultados!!!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 10/83
Dividir e Conquistar
●
Exemplo da aplicação da técnica:
●
Como somar N números, a1, a2, ..., an?
●
Eficiência????
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 11/83
Dividir e Conquistar
●
Exemplo da aplicação da técnica:
●
Como somar N números, a1, a2, ..., an?
●
Eficiência????
●
O(n)......(Melhor que uma abordagem “exaustiva”????)
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 12/83
Dividir e Conquistar
●
Exemplo da aplicação da técnica:
●
Como somar N números, a1, a2, ..., an?
●
Eficiência????
●
O(n)......(Melhor que uma abordagem “exaustiva”????)
●
Claramente NÃO!!!!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 13/83
Dividir e Conquistar
●
Exemplo da aplicação da técnica:
●
Como somar N números, a1, a2, ..., an?
●
Eficiência????
●
O(n)......(Melhor que uma abordagem “exaustiva”????)
●
Claramente NÃO!!!!
●
Portanto, aplicar “Divisão e Conquista” não garante,
por si só, a obtenção de algoritmos eficientes!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 14/83
Dividir e Conquistar
●
OUTRO exemplo: Buscar um elemento!
Como encontrar o elemento em um vetor de tamanho
N: a1, a2, ..., an?
● Se n é 1, e o elemento a é o procurado, achou,
1
senão não achou!
● Se n>1, podemos dividir o problema em dois subproblemas menores:
1.Encontrar o elemento no vetor de a1 até an/2
●
2.Encontrar o elemento no vetor de an/2 até an
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 15/83
Dividir e Conquistar
●
Mas esta técnica não consegue gerar
resultados melhores que a “Força Bruta”???
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 16/83
Dividir e Conquistar
●
Mas esta técnica não consegue gerar
resultados melhores que a “Força Bruta”???
Pode sim.....
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 17/83
Dividir e Conquistar
●
Mas esta técnica não consegue gerar
resultados melhores que a “Força Bruta”???
Pode sim.....
●
Basta aplicá-la “adequadamente”......!
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 18/83
Dividir e Conquistar
●
Mas esta técnica não consegue gerar
resultados melhores que a “Força Bruta”???
Pode sim.....
●
Basta aplicá-la “adequadamente”......!
●
Exemplo de uso adequado: “Busca Binária”.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 19/83
Dividir e Conquistar
Busca Binária:
●
●
Encontrar um determinado elemento (chave) em um vetor
ordenado de tamanho N: a1, a2, ..., an?:
●
Verificar se a chave está na posição ax = an/2:
●
Se estiver, encontrou!
●
Se não estiver, realizar a busca binária nos vetores:
a1 até ax-1,se chave < ax ,
ou em ax+1 até an se chave > ax.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 20/83
Dividir e Conquistar
Busca Binária: Exemplo:
●
Encontrar o número 12 na lista:
3 5 7 8 9 11 12 19
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 21/83
Dividir e Conquistar
Busca Binária: Exemplo:
●
Encontrar o número 12 na lista:
3 5 7 8 9 11 12 19
3 5 7 8 9 11 12 19 (está na posição X=n/2?)Ñ!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 22/83
Dividir e Conquistar
Busca Binária: Exemplo:
●
Encontrar o número 12 na lista:
3 5 7 8 9 11 12 19
3 5 7 8 9 11 12 19 (está na posição X=n/2?)Ñ!
3 5 7 8 9 11 12 19 (está na posição X=n/2?)S!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 23/83
Dividir e Conquistar
Busca Binária:
●
●
Tá, mas e daí????
●
Bem, a eficiência deste algoritmo é Θ(lg n)....
●
Muito mais eficiente que a abordagem “Força Bruta”.....
....pena que o vetor precisa estar ordenado.......
●
....mas podemos aplicar a técnica de Divisão e Conquista
●
para ordenar vetores também!!!!!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 24/83
Dividir e Conquistar
●
Ordenação com Divisão e Conquista:
● Problema: Ordenar um vetor de tamanho N: a , a , ...,
1
2
an
● Um vetor de um elemento já está ordenado!
● Um vetor de tamanho n pode ser ordenado pela
“intercalação” de dois sub-vetores:
1.Um vetor de a1 até an/2
2.Outro vetor de an/2 até an
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 25/83
Dividir e Conquistar
●
Ordenação com Divisão e Conquista:
● Problema: Ordenar um vetor de tamanho N: a , a , ...,
1
2
an
● Um vetor de um elemento já está ordenado!
● Um vetor de tamanho n pode ser ordenado pela
“intercalação” de dois sub-vetores:
1.Um vetor de a1 até an/2
2.Outro vetor de an/2 até an
● Esta maneira de ordenar dá origem ao algoritmo
recursivo de ordenação “MergeSort”!!!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 26/83
Dividir e Conquistar
●
Ordenação com Divisão e Conquista:
● Problema: Ordenar um vetor de tamanho N: a , a , ...,
1
2
an
● Um vetor de um elemento já está ordenado!
● Um vetor de tamanho n pode ser ordenado pela
“intercalação” de dois sub-vetores:
1.Um vetor de a1 até an/2
2.Outro vetor de an/2 até an
● Esta maneira de ordenar dá origem ao algoritmo
recursivo de ordenação “MergeSort”!!!
● Isto é projetar um algoritmo por divisão e conquista!!!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 27/83
Dividir e Conquistar
●
MergeSort:
●
Se a função “intercala” for eficiente=O(n)
●
Detalhe: para conseguir implementar a intercalação de
forma eficiente, é necessário um “vetor auxiliar”, o que
aumenta a memória necessária para o algoritmo...não é
uma ordenação “in-place”,como a Ordenação por
Seleção
●
T(n) = 2T(n/2) + O(n)
●
Logo, Mergesort é Θ(n lg n) (Master)
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 28/83
Dividir e Conquistar
●
MergeSort(A, e, d): : Pseudo-Código
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 29/83
Dividir e Conquistar
●
Intercala(A, e, d): Pseudo-Código
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 30/83
Dividir e Conquistar
Aplicando “Dividir e Conquistar” de outra forma:
● Seja S um conjunto de n ≥ 2 inteiros e x um elemento
qualquer de S.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 31/83
Dividir e Conquistar
Aplicando “Dividir e Conquistar” de outra forma:
● Seja S um conjunto de n ≥ 2 inteiros e x um elemento
qualquer de S.
● Sejam S1 e S2 os subconjuntos de {S − x} dos
elementos menores ou iguais a x e maiores que x,
respectivamente.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 32/83
Dividir e Conquistar
Aplicando “Dividir e Conquistar” de outra forma:
● Seja S um conjunto de n ≥ 2 inteiros e x um elemento
qualquer de S.
● Sejam S1 e S2 os subconjuntos de {S − x} dos
elementos menores ou iguais a x e maiores que x,
respectivamente.
● Ambos S1 e S2 possuem menos de n elementos. Por
hipótese de indução, sabemos ordenar os conjuntos
S1 e S2.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 33/83
Dividir e Conquistar
Aplicando “Dividir e Conquistar” de outra forma:
● Seja S um conjunto de n ≥ 2 inteiros e x um elemento
qualquer de S.
● Sejam S1 e S2 os subconjuntos de {S − x} dos
elementos menores ou iguais a x e maiores que x,
respectivamente.
● Ambos S1 e S2 possuem menos de n elementos. Por
hipótese de indução, sabemos ordenar os conjuntos
S1 e S2.
● Podemos obter S ordenado concatenando S1
ordenado, x e S2 ordenado.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 34/83
Dividir e Conquistar
Aplicando “Dividir e Conquistar” de outra forma:
● Seja S um conjunto de n ≥ 2 inteiros e x um elemento
qualquer de S.
● Sejam S1 e S2 os subconjuntos de {S − x} dos
elementos menores ou iguais a x e maiores que x,
respectivamente.
● Ambos S1 e S2 possuem menos de n elementos. Por
hipótese de indução, sabemos ordenar os conjuntos
S1 e S2.
● Podemos obter S ordenado concatenando S1
ordenado, x e S2 ordenado.
● Esta abordagem dá origem ao algoritmo “QuickSort”!!!
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 35/83
Dividir e Conquistar
Em contraste ao Mergesort, no Quicksort é a operação
de divisão que é mais custosa: depois de escolhermos o
pivô(x), temos que separar os elementos do vetor
maiores que o x dos menores ou iguais a x.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 36/83
Dividir e Conquistar
Em contraste ao Mergesort, no Quicksort é a operação
de divisão que é mais custosa: depois de escolhermos o
pivô(x), temos que separar os elementos do vetor
maiores que o x dos menores ou iguais a x.
●Conseguimos fazer essa divisão com (n) operações:
basta varrer o vetor com dois apontadores, um varrendo
da direita para a esquerda e outro da esquerda para a
direita, em busca de elementos situados na parte errada
do vetor, e trocar um par de elementos de lugar quando
encontrado.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 37/83
Dividir e Conquistar
Em contraste ao Mergesort, no Quicksort é a operação
de divisão que é mais custosa: depois de escolhermos o
pivô(x), temos que separar os elementos do vetor
maiores que o x dos menores ou iguais a x.
●Conseguimos fazer essa divisão com (n) operações:
basta varrer o vetor com dois apontadores, um varrendo
da direita para a esquerda e outro da esquerda para a
direita, em busca de elementos situados na parte errada
do vetor, e trocar um par de elementos de lugar quando
encontrado.
●Após essa etapa basta ordenarmos os dois trechos do
vetor recursivamente para obtermos o vetor ordenado, ou
seja, a conquista é imediata.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 38/83
Dividir e Conquistar
●
Quicksort(A,e,d) - Pseudo-Código:
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 39/83
Dividir e Conquistar
●
Quicksort(A,e,d) - Pseudo-Código(cont):
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 40/83
Dividir e Conquistar
Quicksort- Idéia Base
1. Selecionar um elemento para ser o pivô
2. Rearranjar a lista de modo que todos os elementos
nas posições a esquerda do pivô sejam menores ou
iguais a ele, e aqueles a direita do pivô sejam maiores
que ele.
3. Permutar o pivô com o último elemento da primeira
sub-lista(menores ou iguais). Agora o pivô está em sua
posição final.
4. Ordenar as duas sub-listas.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 41/83
Dividir e Conquistar
QuickSort – Exemplo
●
5 3 1 9 8 2 4 7
partition
2 3 1 4 5 8 9 7
2 3 1 4
partition
1 2 3 4
partition
1
3 4
partition
4
8 9 7
partition
7 8 9
7
9
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 42/83
Dividir e Conquistar
●
●
Quicksort – Análise da Complexidade
Quantas comparações e quantas trocas o algoritmo
Quicksort executa no pior caso ?
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 43/83
Dividir e Conquistar
●
●
●
Quicksort – Análise da Complexidade
Quantas comparações e quantas trocas o algoritmo
Quicksort executa no pior caso ?
Certamente a operação de divisão tem complexidade (n),
mas o tamanho dos dois subproblemas depende do pivô
escolhido.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 44/83
Dividir e Conquistar
●
●
●
●
Quicksort – Análise da Complexidade
Quantas comparações e quantas trocas o algoritmo
Quicksort executa no pior caso ?
Certamente a operação de divisão tem complexidade (n),
mas o tamanho dos dois subproblemas depende do pivô
escolhido.
No pior caso, cada divisão sucessiva do Quicksort separa
um único elemento dos demais, recaindo na recorrência:
T(n) = 0, se n = 1
T(n) = T(n − 1) + n, se n > 1,
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 45/83
Dividir e Conquistar
●
●
●
●
●
Quicksort – Análise da Complexidade
Quantas comparações e quantas trocas o algoritmo
Quicksort executa no pior caso ?
Certamente a operação de divisão tem complexidade (n),
mas o tamanho dos dois subproblemas depende do pivô
escolhido.
No pior caso, cada divisão sucessiva do Quicksort separa
um único elemento dos demais, recaindo na recorrência:
T(n) = 0, se n = 1
T(n) = T(n − 1) + n, se n > 1,
Portanto, (n2) comparações e trocas são executadas no pior
caso!!!!!!
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 46/83
Dividir e Conquistar
Mas o Quicksort não era o algoritmo de
ordenação mais eficiente????
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 47/83
Dividir e Conquistar
Mas o Quicksort não era o algoritmo de
ordenação mais eficiente????
●
●
Então, o algoritmo Quicksort é assintoticamente menos
eficiente que o Mergesort no pior caso.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 48/83
Dividir e Conquistar
Mas o Quicksort não era o algoritmo de
ordenação mais eficiente????
●
●
●
Então, o algoritmo Quicksort é assintoticamente menos
eficiente que o Mergesort no pior caso.
Entretanto, no caso médio, o Quicksort efetua (n log n)
comparações e trocas.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 49/83
Dividir e Conquistar
Mas o Quicksort não era o algoritmo de
ordenação mais eficiente????
●
●
●
●
Então, o algoritmo Quicksort é assintoticamente menos
eficiente que o Mergesort no pior caso.
Entretanto, no caso médio, o Quicksort efetua (n log n)
comparações e trocas.
Assim, na prática, o Quicksort é bastante eficiente, com
uma vantagem adicional em relação ao Mergesort: é “in
place”, isto é, não utiliza um vetor auxiliar.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 50/83
Dividir e Conquistar
Considerando que o pior caso não ocorre com
freqüência, pois usualmente, pegando um “pivô”
aleatório, é “muito difícil” escolher sempre um pivô
que divida o vetor de tamanho n em dois vetores,
um dos menores e outro dos maiores que o pivô,
com tamanhos (n-1) e 1....
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 51/83
Dividir e Conquistar
Considerando que o pior caso não ocorre com
freqüência, pois usualmente, pegando um “pivô”
aleatório, é “muito difícil” escolher sempre um pivô
que divida o vetor de tamanho n em dois vetores,
um dos menores e outro dos maiores que o pivô,
com tamanhos (n-1) e 1....
●Desta forma, supondo uma divisão do vetor de
tamanho n em dois sub-vetores (n/2), e
considerando o tempo de separação entre os
maiores e os menores que o pivô sendo O(n)....
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 52/83
Dividir e Conquistar
Considerando que o pior caso não ocorre com
freqüência, pois usualmente, pegando um “pivô”
aleatório, é “muito difícil” escolher sempre um pivô
que divida o vetor de tamanho n em dois vetores,
um dos menores e outro dos maiores que o pivô,
com tamanhos (n-1) e 1....
●Desta forma, supondo uma divisão do vetor de
tamanho n em dois sub-vetores (n/2), e
considerando o tempo de separação entre os
maiores e os menores que o pivô sendo O(n)....
●O tempo médio T(n)=2T(n/2)+O(n) = O(n lg n)
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 53/83
Dividir e Conquistar
Ordenação: Mas não há um algoritmo que seja
eficiente em todos os casos, e “in place” ao mesmo
tempo?
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 54/83
Dividir e Conquistar
Ordenação: Mas não há um algoritmo que seja
eficiente em todos os casos, e “in place” ao mesmo
tempo?
● Vocês tinham que perguntar?????
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 55/83
Dividir e Conquistar
Ordenação: Mas não há um algoritmo que seja
eficiente em todos os casos, e “in place” ao mesmo
tempo?
● Vocês tinham que perguntar?????
● Este algoritmo chama-se “HeapSort”.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 56/83
Dividir e Conquistar
Ordenação: Mas não há um algoritmo que seja
eficiente em todos os casos, e “in place” ao mesmo
tempo?
● Vocês tinham que perguntar?????
● Este algoritmo chama-se “HeapSort”.
● E é baseado numa estrutura de dados “inteligente”
denominada “Heap”..... implementa uma “fila de
prioridades”....
● Podermos utilizá-la para fazer uma ordenação “inplace” e Θ(n lg n)!!!!
● (Mas o Quicksort ainda é mais rápido!!!!)
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 57/83
Dividir e Conquistar
Ordenação por Heap(HeapSort):
● Tarefa: Implementar a estrutura de dados “Heap” para
podermos utilizá-la para fazer uma ordenação “in-place”
e Θ(n lg n)!!!!
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 58/83
Dividir e Conquistar
Ordenação por Heap(HeapSort):
● Tarefa: Implementar a estrutura de dados “Heap” para
podermos utilizá-la para fazer uma ordenação “in-place”
e Θ(n lg n)!!!!
● Mas o que é um Heap???
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 59/83
Dividir e Conquistar
Ordenação por Heap(HeapSort):
● Tarefa: Implementar a estrutura de dados “Heap” para
podermos utilizá-la para fazer uma ordenação “in-place”
e Θ(n lg n)!!!!
● Mas o que é um Heap???
● É uma “simulação” de uma árvore binária completa
utilizando um vetor!!!!
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 60/83
Dividir e Conquistar
Heap:
● Vetor que apresenta as seguintes características:
●
Vetor A de tamanho N (lenght(A) = nº de nodos da árvore)
● A[1] = raiz da árvore binária (primeira posição do vetor)
● Para calcular a posição de qualquer nodo, utilizamos as
funções PARENT, LEFT E RIGHT:
PARENT(i)
return ⌊i/2⌋
LEFT(i)
return 2i
RIGHT(i)
return 2i + 1
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 61/83
Dividir e Conquistar
●
Heap: (Cormen)
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 62/83
Dividir e Conquistar
Heap:
●
Característica que distingue um Heap de uma
árvore binária :
●
A[PARENT(i)] ≥ A[i] (Max-Heap)
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 63/83
Dividir e Conquistar
●
Como utilizar um Heap para Ordenar????
●
●
●
O Heap permite que o elemento máximo do conjunto seja
determinado e corretamente posicionado no vetor em
tempo constante, trocando o primeiro elemento do heap
com o último.
O trecho restante do vetor (do índice 1 ao n −1), que pode
ter deixado de ter a estrutura de heap, volte a tê-la com
número de trocas de elementos proporcional à altura da
árvore.
O algoritmo Heapsort consiste então da construção de um
heap com os elementos a serem ordenados, seguida de
sucessivas trocas do primeiro com o último elemento e
rearranjos do heap.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 64/83
Dividir e Conquistar
●
HeapSort(A, n) - Pseudo-Código:
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 65/83
Dividir e Conquistar
●
AjustaHeap(A, i, n) - Pseudo-Código:
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 66/83
Dividir e Conquistar
Exemplo do Funcionamento de AjustaHeap(A,2,10):
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 67/83
Dividir e Conquistar
Exemplo do Funcionamento de AjustaHeap(A,2,10):
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 68/83
Dividir e Conquistar
Exemplo do Funcionamento de AjustaHeap(A,2,10):
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 69/83
Dividir e Conquistar
Complexidade do HeapSort:
● Quantas comparações e quantas trocas são
executadas no pior caso na etapa de ordenação do
algoritmo Heapsort?
● No pior caso, a função AjustaHeap efetua (h)
comparações e trocas, onde h é a altura do heap que
contém os elementos que resta ordenar.
● Como o heap representa uma árvore binária completa,
então h ∈ Θ(log i ), onde i é o número de elementos do
heap.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 70/83
Dividir e Conquistar
Complexidade do HeapSort:
● Logo, a complexidade da etapa de ordenação do
Heapsort é:
●
●
●
Portanto, no pior caso, a etapa de ordenação efetua
O(n log n) comparações e trocas!
Mas e a construção do Heap????
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 71/83
Dividir e Conquistar
●
ConstroiHeap()\
Se o trecho de 1 a i do vetor tem estrutura de Heap, é
fácil adicionar a folha i + 1 ao Heap e em seguida
rearranjá-lo,garantindo que o trecho de 1 a i + 1 tem
estrutura de Heap.
● Esta é a abordagem top-down para construção do
Heap.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 72/83
Dividir e Conquistar
●
ConstroiHeap(A, n) – Pseudo-Código (Top-Down):
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 73/83
Dividir e Conquistar
ConstroiHeap(A, n) – (Top-Down):
● Quantas comparações e quantas trocas são
executadas no pior caso na construção do heap pela
abordagem top-down ?
● O rearranjo do heap na iteração i efetua (h)
comparações e trocas no pior caso, onde h é a altura
da árvore representada pelo trecho do Heap de 1 a i .
Logo, h ∈ Θ(log i ).
● Portanto, o número de comparações e trocas
efetuadas construção do Heap por esta abordagem é:
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 74/83
Dividir e Conquistar
Então, o algoritmo Heapsort efetua ao todo Θ (n log n)
comparações e trocas no pior caso.
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 75/83
Dividir e Conquistar
Então, o algoritmo Heapsort efetua ao todo Θ (n log n)
comparações e trocas no pior caso.
●(Bem....sendo mais preciso, executa 2 n log n comparações
e trocas......)
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 76/83
Dividir e Conquistar
Então, o algoritmo Heapsort efetua ao todo Θ (n log n)
comparações e trocas no pior caso.
●(Bem....sendo mais preciso, executa 2 n log n comparações
e trocas......)
●Mas existe maneira mais eficiente de construir um Heap?
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 77/83
Dividir e Conquistar
●
●
●
●
●
●
Suponha que o trecho de i a n do vetor é tal que, para
todo j , i ≤ j ≤ n, a subárvore de raiz j representada por
esse trecho do vetor tem estrutura de heap.
Note que, em particular, o trecho de ⌊n/2⌋ + 1 a n do vetor
satisfaz a propriedade, pois inclui apenas folhas da árvore
binária de n elementos.
Podemos então executar AjustaHeap(A, i − 1, n),
garantindo assim que o trecho de i − 1 a n satisfaz a
propriedade.
Esta é a abordagem bottom-up para construção do Heap.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 78/83
Dividir e Conquistar
●
ConstroiHeap(A, n) – Pseudo-Código Alternativo...:
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 79/83
Dividir e Conquistar
●
ConstroiHeap(A, 6) – Exemplo: A=[2,9,7,6,5,8]
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 80/83
Dividir e Conquistar
●
ConstroiHeap – Complexidade:
●
●
●
●
Quantas comparações e quantas trocas são executadas
no pior caso na construção do Heap pela abordagem
bottom-up ?
O(n lo g n )!
Mas é possível provar matematicamente que este pior
caso é O(n).... utilizando o conhecimento sobre a “altura”
de cada sub-árvore aonde se executa o AjustaHeap().
Ainda assim, o algoritmo HeapSort() continua sendo
Θ(n lo g n )
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 81/83
Dividir e Conquistar
Parte Prática:
● Implementar os algoritmos “MergeSort”, “QuickSort” e
“HeapSort” apresentados, rodar uma “batelada” de
testes para medir os tempos de execução e a quantidade
de comparações executada por cada algoritmo,
comparando os resultados!
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 82/83
Dividir e Conquistar - Conclusão:
●
●
Estes slides são baseados no material
disponibilizado pelos profs. Cid Carvalho de
Souza e Cândida Nunes da Silva, da
UNICAMP.
Qualquer incorretude é, entretanto, de inteira
responsabilidade do prof. João Alberto Fabro,
da UTFPR.
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 83/83
Dividir e Conquistar - Prós e
Contras:
●
Prós:
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 84/83
Dividir e Conquistar - Prós e
Contras:
●
Contras:
●
IF64C – Estruturas de Dados 2 – Engenharia da Computação – Prof. João Alberto Fabro - Slide 85/83
Download