Escolar Documentos
Profissional Documentos
Cultura Documentos
Código implementado:
import time
def fibonacci_recursive(n):
if n <= 1:
return n
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)
def fibonacci(n):
count = 1
n1, n2 = 0, 1
nth = 0
if __name__ == "__main__":
for i in range(1, 31):
start = time.time()
fibonacci_recursive(i)
end = time.time()
print(end-start)
for i in range(1,31):
start = time.time()
fibonacci(i)
end = time.time()
print(end-start)
Gráfico obtido:
Questão 2)
Análise do código:
Pior caso: Chamadas recursivas para a função potência, então T(n) = T(n/2) + 5
T(n) = T(n/2) + 5
utilizando séries:
𝑛
𝑇(𝑛) = 𝑇 ( ) + 5
2
𝑛 𝑛
𝑇 ( ) = 𝑇 ( 2) + 5
2 2
𝑛 𝑛
𝑇 ( ) = 𝑇 ( 3) + 5
3 2
...
𝑛 𝑛
𝑇 ( 𝑙−1 ) = 𝑇 ( 𝑙 ) + 5
2 2
𝑛
=1
2𝑙
𝑛 = 2𝑙
𝑙 = log 2 𝑛
log2 𝑛
1
𝑇(𝑛) = 𝑇(1) + 𝑛 ∗ ∑
2𝑖
𝑖=0
log2 𝑛
1𝑖
𝑇(𝑛) = 𝑇(1) + 𝑛 ∗ ∑
2
𝑖=0
Questão 3b)
𝑇(𝑛) = 2𝑇(𝑛 − 1) + 𝑛
2𝑇(𝑛 − 1) = 22 𝑇(𝑛 − 2) + 2(𝑛 − 1)
22 𝑇(𝑛 − 2) = 23 𝑇(𝑛 − 3) + 22 (𝑛 − 2)
…
𝑇(𝑛) = ∑ 2𝑙 (𝑛 − 1)
𝑖=0
𝑇(𝑛) = ∑ 2𝑖 𝑛 + ∑ 𝑖 ∗ 2𝑖
𝑖=0 𝑖=0
𝑇(𝑛) = 𝑛 ∗ ∑ 2𝑖 + ∑ 𝑖 ∗ 2𝑖
𝑖=0 𝑖=0
∑ 2𝑖 = 20 + 21 + ⋯ + 2𝑛 + 2𝑛+1
𝑖=0
𝑛
𝑖 𝑛+1
∑2 + 2 = 2 + ∑ 2𝑖+1
0
𝑖=0 𝑖=0
𝑛
𝑖 𝑛+1
∑2 + 2 = 2 + 2 ∑ 2𝑖
0
𝑖=0 𝑖=0
𝑛
∑ 2𝑖 = 2𝑛+1 − 1
𝑖=0
𝑇(𝑛) = 𝑛 ∗ ∑ 2𝑖 − ∑ 𝑖 ∗ 2𝑖
𝑖=0 𝑖=0
𝑇(𝑛) = 𝑛 ∗ (2𝑛+1 − 1) − ∑ 𝑖 ∗ 2𝑖
𝑖=0
∑ 𝑖 ∗ 2𝑖 = 0 ∗ 20 + 1 ∗ 21 + 2 ∗ 22 + ⋯ + 𝑛 ∗ 2𝑛 + (𝑛 − 1) ∗ 2𝑛−1
𝑖=0
∑ 𝑖 ∗ 2𝑖 + (𝑛 + 1) ∗ 2𝑛 + 1 = 0 ∗ 20 + ∑(𝑖 + 1) ∗ 2𝑖+1
𝑖=0 𝑖=0
∑ 𝑖 ∗ 2𝑖 + 𝑛 ∗ 2𝑛+1 + 2𝑛+1 = 2 ∗ ∑ 𝑖 ∗ 2𝑖 + 2 ∗ ∑ 2𝑖
𝑖=0 𝑖=0 𝑖=0
∑ 𝑖 ∗ 2𝑖 = 𝑛 ∗ 2𝑛+1 − 2𝑛+1 + 2
𝑖=0
𝑇(𝑛) = 2𝑛+1 − 𝑛 − 2
Questão 3c)
𝑛
𝑇(𝑛) = 4𝑇 ( ) + 𝑛
2
𝑛 𝑛 𝑛
4𝑇 ( 1 ) = 42 𝑇 ( 1 ) + 4 ∗ ( 1 )
2 2 2
𝑛 𝑛 𝑛
42 𝑇 ( 2 ) = 43 𝑇 ( 2 ) + 42 ∗ ( 2 )
2 2 2
…
𝑛 𝑛 𝑛
𝑇(𝑛) = 𝑛 + 41 𝑇 ( 1 ) + 42 𝑇 ( 2 ) + ⋯ + 4𝑙 𝑇( 𝑙 )
2 2 2
𝑛−1
𝑛
𝑇(𝑛) = ∑ 4𝑖 ( 𝑖 )
2
𝑖=0
𝑛−1
𝑇(𝑛) = ∑ 2𝑖 𝑛
𝑖=0
𝑛−1
𝑇(𝑛) = 𝑛 ∗ ∑ 2𝑖
𝑖=0
𝑇(𝑛) = 𝑛 ∗ (2𝑙+1 − 1)
𝑇(𝑛) = 𝑛 ∗ (2 ∗ 2𝑙 − 1)
𝑇(𝑛) = 𝑛 ∗ (2 ∗ 𝑛 − 1)
𝑇(𝑛) = 2𝑛2 − 𝑛
Resultado: 𝑛2 está dominando assintoticamente os outros, portanto T(n) = O(𝑛2 )
Questão 3d)
𝑛
𝑇(𝑛) = 𝑇 ( 1 ) + log 2 𝑛
2
𝑛 𝑛 𝑛
𝑇 ( 1 ) = 𝑇 ( 2 ) + log 2 ( 1 )
2 2 2
𝑛 𝑛 𝑛
𝑇 ( 2 ) = 𝑇 ( 3 ) + log 2 ( 2 )
2 2 2
…
𝑛 𝑛
𝑇(𝑛) = 𝑇 ( 𝑙 ) + log 2 ( 𝑙−1 )
2 2
𝑛
𝑇(𝑛) = 𝑇(1) + log 2 ( 𝑙−1 )
2
𝑛
𝑙 = 𝑙 => 𝑙 = log 2 𝑛
2
log2 (𝑛)−1
𝑛
𝑇(𝑛) = ∑ log 2
2𝑖
𝑖=0
log2 (𝑛)−1
log 2 𝑛
𝑇(𝑛) = ∑
log 2 2𝑖
𝑖=0
log2 (𝑛)−1
log 2 𝑛
𝑇(𝑛) = ∑
𝑖 ∗ log 2 2
𝑖=0
log2 (𝑛)−1
log 2 𝑛
𝑇(𝑛) = ∑
𝑖
𝑖=0
log2 (𝑛)−1
1
𝑇(𝑛) = log 2 𝑛 ∗ ∑
𝑖
𝑖=0
Questão 5)
Inserir inicio:
Inserir final:
A função inserir início não possui nenhum looping nem algo que possa causar uma demora
extra na função, portanto sua velocidade é constante;
Porém a função inserir final possui um loop que passa por todas as posições da lista, como a
lista possui n elementos, a função insert end é O(n)
Questão 6)
Como é uma arvore balanceada, cada um dos nodos à esquerda e à direita devem ter metade
do seu parente, portanto para cada um deles T(n) = T(n/2), o resto da função é executado em
O(1) portanto, para a função imprimir T(n) = 2T(n/2) + O(1), utilizando séries:
𝑛
𝑇(𝑛) = 2𝑇 ( ) + 1
2
𝑛 𝑛
2𝑇 ( ) = 22 𝑇 ( 2 ) + 1
2 2
𝑛 𝑛
22 𝑇 ( 2 ) = 23 𝑇 ( 3 ) + 1
2 2
…
𝑛 𝑛
2𝑙−1 𝑇 ( 𝑙−1 ) = 2𝑙 𝑇 ( 𝑙 ) + 1
2 2
𝑛
=1
2𝑙
𝑛 = 2𝑙
𝑙 = log 2 𝑛
n n n
T(n) + 2T ( ) + 22 T ( 2 ) + ⋯ + 2l−1 T ( l−1 )
2 2 2
n n n n
= 2T ( ) + 2 T ( 2 ) + 23 T ( 3 ) + ⋯ + 2l T ( l )
2
2 2 2 2
𝑛
𝑇(𝑛) = 1 + 1 + 1 + ⋯ + 1 + 2𝑙 𝑇 ( 𝑙 )
2
𝑇(𝑛) = log 2 𝑛 + 𝑛
Como n domina assintoticamente log n, então a complexidade de tempo é O (n)
A complexidade de espaço será a maior altura na pilha, para uma árvore balanceada, esta
altura será de log n, portanto a complexidade de espaço é O (log n)