Você está na página 1de 25

Análise de Algoritmos

Aula 02

Prof. Roberto Leminski


roberto.leminski@docente.unip.br
Conteúdo
•Complexidade de tempo e Espaço

•Recursão

•Heaps
Complexidade de Tempo e Espaço
•A notação Grande-O pode representar dois
tipos de complexidade:

•Tempo de execução

•Espaço de memória
Recursão
•Um algoritmo é dito recursivo quando ele
faz uma chamada a si mesmo.

•Um exemplo clássico de recursão é o


cálculo do fatorial:

•N! = N x (N-1) x (N-2) x ... x 2 x 1


Recursão
•N! = N x (N-1) x (N-2) x ... x 2 x 1

•N! = N x (N-1)!

•N! = N x (N-1) x (N-2)!


Recursão
•Nenhum programa nem função pode ser
exclusivamente definido por si.

• Um programa seria um loop infinito


• Uma função teria definição circular

•Necessário definir uma condição de parada

• No exemplo, define-se 0! =1

• Estrutura em pilha
Recursão
•A complexidade de tempo de uma função
fatorial recursiva é O(n).

•A complexidade de espaço também é O(n),


devido a pilha de execução.

•Já em uma função fatorial não recursiva, a


complexidade de espaço é O(1).
Recursão
•A recursividade nem sempre é a melhor
solução

•Todo algoritmo recursivo tem uma versão


não recursiva

•Vale a pena implementar esta versão não-


recursiva?
Recursão
•Recursividade vale a pena para Algoritmos
complexos, cuja a implementação iterativa é
complexa e normalmente requer o uso
explícito de uma pilha:

•Dividir para Conquistar (Ex. Quicksort)

•Trajeto em Árvores (pesquisa,


backtracking)
Heaps
•Nem toda fila segue a política de acesso
First In First Out (FIFO). Na verdade, em vários
cenários do dia a dia, as filas que entramos
possuem uma política diferente: são filas de
prioridade.

•Em estrutura de dados, precisamos pensar


em como manter a estrutura ordenada tendo
como critério essa prioridade. Vamos analisar
alternativas para implementar filas de
prioridade usando estruturas de dados
lineares.
Heaps
• Em primeiro lugar, os objetos passam a ter
uma prioridade, que é representada por um
atributo inteiro. No nosso exemplo, quanto
maior esse número, maior a prioridade.

•Nesse caso, para implementarmos uma fila


de prioridade, temos que tomar uma decisão:
manter a fila ordenada ou não?
Heaps
•Se decidirmos manter a fila sempre
ordenada tendo como critério a prioridade,
precisamos utilizar o algoritmo de inserção
ordenada, cujo custo é O(n). Contudo, a
extração do maior elemento é O(1), pois ele
sempre está no início da fila.

•Se optarmos por não manter a fila


ordenada por prioridade, temos o cenário
oposto. A adição passa a ser O(1), mas a
remoção do maior passa a ser O(n), pois
teremos que pesquisar em toda a fila a maior
prioridade.
Heaps
•A estrutura que veremos neste material,
Heap, resolve essa questão permitindo que a
adição e extração do máximo sejam ambas
realizadas em O(log n), o que é muito
desejável do ponto de vista de eficiência.

•Além disso, o máximo fica sempre na raiz


dessa estrutura, o que permite sua inspeção
em O(1).
Comparação com Lista Ordenada
•Em uma lista ordenada comum, temos as
seguintes complexidades de tempo;

•Criação: O(n2)

•Inserção: O(n)

•Remoção: O(1).
Heaps
•Heaps são árvores binárias. É importante
observar que são árvores binárias, mas não
são árvores binárias de pesquisa. Mais
especificamente, duas propriedades definem o
Heap:

•1. O valor de um nó é maior ou igual ao


valor de seus filhos;

•2. O Heap é uma árvore binária completa


ou quase-completa da esquerda para a direita.
Heaps
Heaps
Heaps
•Você há de lembrar que boa parte das
operações básicas fundamentais em árvores
binárias são O(h), onde h é a altura da árvore.

•Por isso, é preciso manter a altura próxima


da altura mínima possível. Em uma árvore
binária a altura mínima é O(log n).
Heaps
•Por isso a segunda propriedade de Heap é
tão importante. Porque uma árvore completa
ou quase-completa possui a altura O(log n).

•Por construção, a altura de um Heap é


O(log n), pois é uma estrutura completa ou
quase completa da esquerda para a direita.
Essa propriedade permite que as operações
de inserção e remoção sejam eficientes.
Representado Heaps como Vetores
•Podemos utilizar um array para
implementar o Heap.

•Então, antes precisamos entender como os


elementos dispostos em um array podem
representar um Heap.
Representado Heaps como Vetores

•O array que representa esse Heap é heap =


[48,24,45,14].
Representado Heaps como Vetores

•O array que representa esse Heap é heap =


[88,87,73,47,54,6,0,43].
Referências
• DASGUPTA, Sanjoy. Christos Papadimitriou,
Umesh Vazirani. Algoritmos. Porto Alegre, RS:
AMGH, 2011.
Dúvidas ?
Obrigado !

Você também pode gostar