Você está na página 1de 99

SBVESDD: Estruturas

de Dados

Aula 05: Introdução à Análise de Algoritmos

Tecnologia em Sistemas para Internet


Prof. Dr. David Buzatto
2/99
Algumas Perguntas...

 Em quanto tempo terei a resposta?


 Porque o meu programa está tão lento?
 Quanto de memória vou precisar?
 Consigo executar este algoritmo com muitos dados?
 Se eu comprar um computador 2 vezes mais rápido, terei minha resposta em
tempo hábil?
 Vale a pena comprar mais memória?
 Em uma aplicação prática terei 10 vezes mais dados, este
algoritmo será útil?

"People who analyze algorithms have double happiness. First of all they experience the
sheer beauty of elegant mathematical patterns that surround elegant computational
procedures. Then they receive a practical payoff when their theories make it possible to
get other jobs done more quickly and more economically." - Donald Knuth
3/99
Análise de Algoritmos

 Entender o comportamento de um algoritmo em função da carga


de dados que deve ser processada;
 Avaliar o custo em termos de tempo e de espaço;
 Tempo: tempo de processamento;
 Espaço: espaço em memória utilizado.
4/99
Análise de Algoritmos

Estudaremos
 Entender o comportamento de umessealgoritmo
aspecto! em função da carga
de dados que deve ser processada;
 Avaliar o custo em termos de tempo e de espaço;
 Tempo: tempo de processamento;
 Espaço: espaço em memória utilizado.
5/99
Análise de Algoritmos

 Dados dois ou mais algoritmos que resolvem o mesmo problema,


determinar qual é o melhor ou o pior, dependendo da carga de
dados;
 A quantidade de dados é relevante, pois um algoritmo julgado pior
que outro para grandes quantidades de dados, pode ser melhor
para quantidades pequenas.
6/99
Análise de Algoritmos

 Complexidade de algoritmos: processo de avaliação dos


comandos dos algoritmos com o objetivo de estimar seu tempo de
execução em função da carga de dados;
 Carga de dados: é o tamanho do problema;
 Exemplos: tamanho de um array, termo de uma série (fibonacci),
fatorial de um número etc.
7/99
Melhor caso, pior caso e caso médio

 O tempo de execução alguns algoritmos dependem não somente


da quantidade de dados, mas também do estado desses dados;
 Exemplo: um array desordenado precisa ser ordenado;
 O algoritmo de cálculo do fatorial não depende do estado, mas
algoritmos de ordenação dependem.
8/99
Melhor caso, pior caso e caso médio

Três situações:
Favorável ➔ melhor caso;
Desfavorável ➔ pior caso;
Ordinária ➔ caso normal ou caso médio.
9/99
Melhor caso, pior caso e caso médio

Exemplo: busca sequencial de um valor em um array que


não contém valores repetidos;
Se houver alguma tendência do número pesquisado ficar no
início do array, o algoritmo executará de forma mais rápida, ou
seja, o melhor caso.

public static int search( int[] array, int key ) {


int n = array.length;
for ( int i = 0; i < n; i++ ) {
if ( array[i] == key ) {
return i;
}
}
return -1;
}
10/99
Melhor caso, pior caso e caso médio

Exemplo: busca sequencial de um valor em um array que


não contém valores repetidos;
Se o valor pesquisado não existir no array ou houver tendência
do valor ficar no fim do array, o algoritmo executará de forma
mais lenta, ou seja, o pior caso.

public static int search( int[] array, int key ) {


int n = array.length;
for ( int i = 0; i < n; i++ ) {
if ( array[i] == key ) {
return i;
}
}
return -1;
}
11/99
Melhor caso, pior caso e caso médio

Exemplo: busca sequencial de um valor em um array que


não contém valores repetidos;
Se não houver tendência, o algoritmo percorrerá em média a
metade dos itens do array, ou seja, o caso médio (distribuição
normal).
12/99
Complexidade Assintótica

 Análise da complexidade de algoritmos onde o tamanho do


problema tende ao infinito;
 Ou seja, o que importa são cargas muito grandes de dados, não
de 100, 200 ou 300 itens, mas sim de milhares ou milhões de
elementos;
 Exemplos: consultas em bases de dados, ordenação de uma lista
telefônica etc.
13/99
Aspectos Formais e Notação

 n: tamanho do problema. Valor que o tempo de execução


depende;
 É sempre maior ou igual a zero;
 Exemplos: tamanho de um array, fatorial de um número, quantidade
de nós de uma árvore binária etc.
14/99
Aspectos Formais e Notação

 T(n): função que reflete o tempo de execução de um algoritmo de


carga n;
 É sempre positiva;
 A avaliação das características de T(n) é a análise de complexidade
do algoritmo.
15/99
Aspectos Formais e Notação

 Notação O (Big-Oh/Ômicrom): Representa o conjunto de funções


que limita superiormente o comportamento de um algoritmo;
 Notação Ω (Ômega): Representa o conjunto de funções que limita
inferiormente o comportamento de um algoritmo;
 Notação (Teta): Representa o conjunto de funções que limita
tanto superiormente quanto inferiormente o comportamento de um
algoritmo.
16/99
Aspectos Formais e Notação

 𝑶(𝒈(𝒏)): notação de complexidade O;


 Representa as características globais sobre o comportamento de
um algoritmo, neste caso, o limite superior;
 Formalmente, o conjunto de funções 𝑶(𝒈(𝒏)) é definido como:

𝑂(𝑔(𝑛)) = { 𝑓(𝑛) ∶ existem constantes positivas 𝒄 e 𝒏𝟎,


tal que 0 ≤ 𝑓(𝑛) ≤ 𝑐𝑔(𝑛), para todo 𝑛 ≥ 𝑛0 }
17/99
Aspectos Formais e Notação

𝑂(𝑔(𝑛)) = { 𝑓(𝑛) ∶ existem constantes positivas 𝒄 e 𝒏𝟎,


tal que 0 ≤ 𝑓(𝑛) ≤ 𝑐𝑔(𝑛), para todo 𝑛 ≥ 𝑛0 }
18/99
Aspectos Formais e Notação

 Exemplos:
 𝑇 𝑛 = 𝑛2 + 𝑛 + 10 (é) 𝑂(𝑛2)
 𝑇 𝑛 = 3𝑛3 + 𝑛2 (é) 𝑂(𝑛3)
 𝑇 𝑛 = 50 lg 𝑛 + 30 (é) 𝑂(lg 𝑛)*
𝑛 lg 𝑛
𝑇 𝑛 = + 4𝑛 (é) 𝑂(𝑛 lg 𝑛)*
3

*a notação lg 𝑛 é equivalente a log2 𝑛


19/99
Aspectos Formais e Notação

 Exemplo:
Para 𝑂 𝑛2 , 𝑇 𝑛 = 𝑛2
Sendo assim:
se n = 10, 𝑇 10 = 102 = 100
se n = 100, 𝑇 100 = 1002 = 10000
Pois:
𝑇 𝑛 = 𝑛2
𝑇 10𝑛 = (10𝑛)2 = 100𝑛2 = 100𝑇(𝑛)

Ou seja: para um algoritmo de complexidade 𝑂(𝑛2 ), o aumento da


carga em 10 vezes, implica no aumento no tempo em 100 vezes!
20/99
Aspectos Formais e Notação

𝑂(𝑔(𝑛)) = { 𝑓(𝑛) ∶ existem constantes positivas 𝒄 e 𝒏𝟎,


tal que 0 ≤ 𝑓(𝑛) ≤ 𝑐𝑔(𝑛), para todo 𝑛 ≥ 𝑛0 }

 𝑇(𝑛) pertence a 𝑂(𝑔(𝑛)) se e somente se 𝑇(𝑛) ≤ 𝑐𝑔(𝑛), para todos


os valores de 𝑛 ≥ 𝑛0, com 𝑐 e 𝑛0 positivos e arbitrários;
 Ou seja, se, a partir de um dado tamanho de problema (𝑛), o
tempo de execução do algoritmo (𝑇(𝑛)) for limitado superiormente
por uma função (𝑔(𝑛)) multiplicada por uma constante (𝑐), então a
notação de qualificação 𝑂(𝑔(𝑛)) pode ser usada para indicar a
complexidade do algoritmo ou sua ordem de crescimento.
21/99
Aspectos Formais e Notação

 Exemplo 1: Se 𝑇(𝑛) = 50𝑛 + 20, mostre que 𝑇(𝑛) pertence a 𝑂(𝑛).


 Para 𝑇(𝑛) pertencer a 𝑂(𝑛), 50𝑛 + 20 ≤ 𝑐𝑛
 Deve-se mostrar que existem valores para 𝑐 e 𝑛0 que façam com que
𝑇(𝑛) ≤ 𝑐𝑛 seja válido para 𝑛 ≥ 𝑛0
22/99
Aspectos Formais e Notação
23/99
Aspectos Formais e Notação

𝒏 ≥ 𝟐𝟎
24/99
Aspectos Formais e Notação

𝒏 ≥ 𝟐𝟎

Para 𝑐 = 51, 𝑇(𝑛) ≤ 51𝑛 para todo 𝑛 ≥ 20


25/99
Aspectos Formais e Notação

 Exemplo 2: Se 𝑇(𝑛) = 10𝑛2 + 3𝑛 + 4, mostre que 𝑇(𝑛) pertence a


𝑂(𝑛2).
 Para 𝑇(𝑛) pertencer a 𝑂(𝑛2), 10𝑛2 + 3𝑛 + 4 ≤ 𝑐𝑛2
 Deve-se mostrar que existem valores para 𝑐 e 𝑛0 que façam com que
𝑇(𝑛) ≤ 𝑐𝑛2 seja válido para 𝑛 ≥ 𝑛0
26/99
Aspectos Formais e Notação
27/99
Aspectos Formais e Notação

𝒏 ≥ 𝟒
28/99
Aspectos Formais e Notação

𝒏 ≥ 𝟒
Para 𝑐 = 11, 𝑇(𝑛) ≤ 11𝑛2 para todo 𝑛 ≥ 4
29/99
Aspectos Formais e Notação

 Funções mais usadas para indicar a complexidade de algoritmos:

Ordem relativa Função Nome


1 1 Constante
2 lg 𝑛 Logarítmica
3 𝑛 Linear (polinomial)
4 𝑛 lg 𝑛 Linear-Logarítmica
5 𝑛2 Quadrática (polinomial)
6 𝑛3 Cúbica (polinomial)
7 2𝑛 Exponencial

 Obs: a notação lg indica logaritmo de base 2


30/99
Aspectos Formais e Notação
31/99
Aspectos Formais e Notação
32/99
Aspectos Formais e Notação
33/99
Aspectos Formais e Notação
34/99
Aspectos Formais e Notação
Escala logarítmica
35/99
O Impacto da Complexidade

 Tempos de execução para algoritmos de complexidades variadas,


supondo um computador que execute uma instrução por
microssegundo:
O(lg n) O(n lg n)
36/99
O Impacto da Complexidade

 Tamanho do problema que seria executado em um período fixo de


tempo, caso a velocidade de processamento fosse aumentada:
37/99
O Impacto da Complexidade
Se o processador original for
trocado por um 100 vezes
 Tamanho do problema que seria executado emeuum
mais rápido, período fixo de
consigo
tempo, caso a velocidade de processamento fosse aumentada:
resolver um problema 100
vezes maior que o original
no mesmo tempo.
38/99
O Modelo de Computador e os Comandos

Algoritmo:
c = a + b;
Considerar:
Tempo de acesso à memória (a e b);
Realização da operação (soma);
Armazenamento do resultado em local temporário;
Atribuição do valor obtido em c.
39/99
O Modelo de Computador e os Comandos

 O tempo da realização dessas operações pode variar de máquina


para máquina;
 Detalhes muito finos podem ser desconsiderados na análise de
algoritmos. Por quê?
40/99
O Modelo de Computador e os Comandos

 O tempo da realização dessas operações pode variar de máquina


para máquina;
 Detalhes muito finos podem ser desconsiderados na análise de
algoritmos. Por quê?
 Porque não estamos interessados em absolutamente todos os detalhes
de cada operação que um algoritmo irá realizar, mas sim nas que
influenciam a execução do algoritmo com base no tamanho do
problema, tentando assim encontrar qual a ordem de crescimento do
mesmo;
 Ainda assim, nesta disciplina tentaremos encontrar uma função que
modele o tempo gasto no processamento de um problema
considerando todas as instruções do mesmo, mas simplificando como
iremos contar o tempo gasto por cada uma delas.
41/99
O Modelo de Computador e os Comandos

 Sendo assim, por mais diferentes que as operações sejam, devemos


considerar que cada uma gastará apenas uma unidade de tempo;
 No algoritmo “c = a + b;”, são gastas 4 unidades de tempo (ut):
 Duas para a obtenção de a e b;
 Uma para a soma;
 Uma para a atribuição.
42/99
O Modelo de Computador e os Comandos

 Reforça-se que mesmo o nível de detalhe apresentado


anteriormente será desnecessário, visto que estamos preocupados
com a “cara” da função de tempo e não com os valores dos
coeficientes que a compõe.
43/99
Definindo 𝑇(𝑛) e Classificando-a

 Tempo constante?
 Com repetições?
 Dependente de n?
 Ordem polinomial dependente da profundidade/aninhamento de estruturas de
repetição;
 Independente de n?
 Divisão e conquista?
44/99
Trechos com Repetições

 Tipo principal de estrutura que influencia no consumo de tempo;


 O aninhamento de repetições que tenham as características
mostradas (que tenham como base o tamanho do problema em
sua condição de parada) acarretam no aumento do grau do
polinômio;
45/99
Trechos com Repetições

public static int somatorio( int n ) {

int soma = 0;

for ( int i = 1; i <= n; i++ ) {


soma += i;
}

return soma;

Tempo da instrução

Quantidade de execuções
46/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut
int soma = 0;

for ( int i = 1; i <= n; i++ ) {


soma += i;
}

return soma;

Tempo da instrução

Quantidade de execuções
47/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut
int soma = 0;
1ut
for ( int i = 1; i <= n; i++ ) {
soma += i;
}

return soma;

Tempo da instrução

Quantidade de execuções
48/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut
int soma = 0;
1ut 3ut
for ( int i = 1; i <= n; i++ ) {
soma += i;
}

return soma;

Tempo da instrução

Quantidade de execuções
49/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut
int soma = 0;
1ut 3ut 1ut
for ( int i = 1; i <= n; i++ ) {
soma += i;
}

return soma;

Tempo da instrução

Quantidade de execuções
50/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut
int soma = 0;
1ut 3ut 1ut
for ( int i = 1; i <= n; i++ ) {
soma += i; 2ut
}

return soma;

Tempo da instrução

Quantidade de execuções
51/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut
int soma = 0;
1ut 3ut 1ut
for ( int i = 1; i <= n; i++ ) {
soma += i; 2ut
}
1ut
return soma;

Tempo da instrução

Quantidade de execuções
52/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 3ut 1ut
for ( int i = 1; i <= n; i++ ) {
soma += i; 2ut
}
1ut
return soma;

Tempo da instrução

Quantidade de execuções
53/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut 1ut
for ( int i = 1; i <= n; i++ ) {
soma += i; 2ut
}
1ut
return soma;

Tempo da instrução

Quantidade de execuções
54/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut
for ( int i = 1; i <= n; i++ ) {
soma += i; 2ut
}
1ut
return soma;

Tempo da instrução

Quantidade de execuções
55/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut
return soma;

Tempo da instrução

Quantidade de execuções
56/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut
return soma;

Tempo da instrução

Quantidade de execuções
57/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut 1
return soma;

Tempo da instrução

Quantidade de execuções
58/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut 1
return soma;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 2𝑛 + 1

Tempo da instrução

Quantidade de execuções
59/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut 1
return soma;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 2𝑛 + 1

Tempo da instrução

Quantidade de execuções
60/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut 1
return soma;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 2𝑛 + 1

Tempo da instrução

Quantidade de execuções
61/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut 1
return soma;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 2𝑛 + 1

Tempo da instrução

Quantidade de execuções
62/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut 1
return soma;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 2𝑛 + 1

Tempo da instrução

Quantidade de execuções
63/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut 1
return soma;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 2𝑛 + 1

Tempo da instrução

Quantidade de execuções
64/99
Trechos com Repetições

public static int somatorio( int n ) {


1ut 1
int soma = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 1; i <= n; i++ ) {
n soma += i; 2ut
}
1ut 1
return soma;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 2𝑛 + 1

Tempo da instrução

Quantidade de execuções
65/99
Trechos com Repetições

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 2𝑛 + 1
𝑇 𝑛 = 3 + 3𝑛 + 3 + 3𝑛
𝑇 𝑛 = 6𝑛 + 6

𝑇 𝑛 é 𝑂(𝑛)
66/99
Trechos com Repetições
public static int k( int n ) {

int x = 0;

for ( int i = 0; i < n; i++ ) {

for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3;

return x;

Tempo da instrução

Quantidade de execuções
67/99
Trechos com Repetições
public static int k( int n ) {
1ut
int x = 0;

for ( int i = 0; i < n; i++ ) {

for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3;

return x;

Tempo da instrução

Quantidade de execuções
68/99
Trechos com Repetições
public static int k( int n ) {
1ut
int x = 0;
1ut
for ( int i = 0; i < n; i++ ) {

for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3;

return x;

Tempo da instrução

Quantidade de execuções
69/99
Trechos com Repetições
public static int k( int n ) {
1ut
int x = 0;
1ut 3ut
for ( int i = 0; i < n; i++ ) {

for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3;

return x;

Tempo da instrução

Quantidade de execuções
70/99
Trechos com Repetições
public static int k( int n ) {
1ut
int x = 0;
1ut 3ut 1ut
for ( int i = 0; i < n; i++ ) {

for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3;

return x;

Tempo da instrução

Quantidade de execuções
71/99
Trechos com Repetições
public static int k( int n ) {
1ut
int x = 0;
1ut 3ut 1ut
for ( int i = 0; i < n; i++ ) {
1ut
for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3;

return x;

Tempo da instrução

Quantidade de execuções
72/99
Trechos com Repetições
public static int k( int n ) {
1ut
int x = 0;
1ut 3ut 1ut
for ( int i = 0; i < n; i++ ) {
1ut 3ut
for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3;

return x;

Tempo da instrução

Quantidade de execuções
73/99
Trechos com Repetições
public static int k( int n ) {
1ut
int x = 0;
1ut 3ut 1ut
for ( int i = 0; i < n; i++ ) {
1ut 3ut 1ut
for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3;

return x;

Tempo da instrução

Quantidade de execuções
74/99
Trechos com Repetições
public static int k( int n ) {
1ut
int x = 0;
1ut 3ut 1ut
for ( int i = 0; i < n; i++ ) {
1ut 3ut 1ut
for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3; 6ut

return x;

Tempo da instrução

Quantidade de execuções
75/99
Trechos com Repetições
public static int k( int n ) {
1ut
int x = 0;
1ut 3ut 1ut
for ( int i = 0; i < n; i++ ) {
1ut 3ut 1ut
for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
76/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 3ut 1ut
for ( int i = 0; i < n; i++ ) {
1ut 3ut 1ut
for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
77/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut 1ut
for ( int i = 0; i < n; i++ ) {
1ut 3ut 1ut
for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
78/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut
for ( int i = 0; i < n; i++ ) {
1ut 3ut 1ut
for ( int j = 0; j < n; j++ ) {

x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
79/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut
for ( int i = 0; i < n; i++ ) {
1ut 3ut 1ut
for ( int j = 0; j < n; j++ ) {

n x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
80/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 3ut 1ut
for ( int j = 0; j < n; j++ ) {

n x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
81/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 1 3ut 1ut
for ( int j = 0; j < n; j++ ) {

n x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
82/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 1 3ut n+1 1ut
for ( int j = 0; j < n; j++ ) {

n x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
83/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 1 3ut n+1 1ut
for ( int j = 0; j < n; j++ ) {

n n x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
84/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 1 3ut n+1 1ut n
for ( int j = 0; j < n; j++ ) {

n n x *= ( i * 2 / j ) / 3; 6ut

}
1ut
return x;

Tempo da instrução

Quantidade de execuções
85/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 1 3ut n+1 1ut n
for ( int j = 0; j < n; j++ ) {

n n x *= ( i * 2 / j ) / 3; 6ut

}
1ut 1
return x;

Tempo da instrução

Quantidade de execuções
86/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 1 3ut n+1 1ut n
for ( int j = 0; j < n; j++ ) {

n n x *= ( i * 2 / j ) / 3; 6ut

}
1ut 1
return x;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 𝑛 1 + 3 𝑛 + 1 + 𝑛 + 6𝑛 + 1
Tempo da instrução

Quantidade de execuções
87/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 1 3ut n+1 1ut n
for ( int j = 0; j < n; j++ ) {

n n x *= ( i * 2 / j ) / 3; 6ut

}
1ut 1
return x;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 𝑛 1 + 3 𝑛 + 1 + 𝑛 + 6𝑛 + 1
Tempo da instrução

Quantidade de execuções
88/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 1 3ut n+1 1ut n
for ( int j = 0; j < n; j++ ) {

n n x *= ( i * 2 / j ) / 3; 6ut

}
1ut 1
return x;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 𝑛 1 + 3 𝑛 + 1 + 𝑛 + 6𝑛 + 1
Tempo da instrução

Quantidade de execuções
89/99
Trechos com Repetições
public static int k( int n ) {
1ut 1
int x = 0;
1ut 1 3ut n+1 1ut n
for ( int i = 0; i < n; i++ ) {
1ut 1 3ut n+1 1ut n
for ( int j = 0; j < n; j++ ) {

n n x *= ( i * 2 / j ) / 3; 6ut

}
1ut 1
return x;

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 𝑛 1 + 3 𝑛 + 1 + 𝑛 + 6𝑛 + 1
Tempo da instrução

Quantidade de execuções
90/99
Trechos com Repetições

𝑇 𝑛 = 1 + 1 + 3 𝑛 + 1 + 𝑛 + 𝑛 1 + 3 𝑛 + 1 + 𝑛 + 6𝑛 + 1
𝑇 𝑛 = 3 + 3𝑛 + 3 + 𝑛 + 𝑛(1 + 3𝑛 + 3 + 7𝑛)
𝑇 𝑛 = 4𝑛 + 6 + 𝑛 + 3𝑛2 + 3𝑛 + 7𝑛2
𝑇 𝑛 = 10𝑛2 + 8𝑛 + 6

𝑇 𝑛 é 𝑂(𝑛2 )
91/99
Outras Considerações

 A análise de algoritmos apresentada leva em consideração o comportamento dos


algoritmos para cargas de dados grandes, entretanto isso não significa que um algoritmo
pertencente a 𝑂(𝑛2) seja pior que um algoritmo 𝑂(𝑛) para todo 𝑛, visto que a avaliação
feita é geral.
92/99
Análise de Algoritmos
Exercícios Escritos

 Exercício e5.1: Defina complexidade assintótica.


 Exercício e5.2: No estudo da análise dos algoritmos, usamos três notações: 𝑛, 𝑇(𝑛)
e 𝑂(𝑓(𝑛)). Explique o significado de cada uma delas.
 Exercício e5.3: Ordene, da mais lenta para a mais rápida, as seguintes notações
de complexidade:
𝑂(𝑛), 𝑂(𝑛2 ), 𝑂(1), 𝑂(𝑛 lg 𝑛), 𝑂(lg 𝑛), 𝑂(𝑛3 ) e 𝑂(2𝑛 ).
93/99
Análise de Algoritmos
Exercícios Escritos

 Exercício e5.4: Calcule a função de tempo de execução dos algoritmos a seguir em


função de 𝑛 e diga a qual classificação de complexidade cada função pertence. Os
algoritmos foram escritos na linguagem Java. Os cálculos devem ser mantidos na
resposta! Considere sempre que necessário que o algoritmo alcançará o pior caso.
Para as contagens, as quantidades abaixo devem ser observadas:
 ut: unidade de tempo arbitrária;
 Declaração de variável ou declaração com atribuição de literal do tipo em questão: 1ut
(ex: int i; ou int i = 0; ou double j = 5.75;);
 Acesso a variáveis: 1ut;
 Operadores de incremento/decremento pré ou pós-fixados: 1ut (ex: i++ ou --i);
 Operações aritméticas, relacionais, lógicas e de atribuição: 1ut (ex: 1 + 2 ou 3 < 4 ou
true && true ou x = 10 etc);
 Operadores de atribuição compostos: 1ut (ex: i += 10 ou j -= 20 etc.)
 Invocação de métodos: 1ut (ex: System.out.println( 20 ));
 Retorno de método: o tempo da expressão à direita da palavra chave return;
 Caso o código seja um método, não levar em consideração seu cabeçalho.
94/99
Análise de Algoritmos
Exercícios Escritos

a)
1 int n = 0;
2 int x = n + 2;
3 System.out.println( x );
b)
1 int n = 4;
2 for ( int i = 0; i <= 10; i++ ) {
3 System.out.printf( "%d x %d = %d", n, i, n*i );
4 }
c)
1 public static int fatorial( int n ) {
2 int fat = 1;
3 for ( int i = 1; i <= n; i++ ) {
4 fat *= i;
5 }
6 return fat;
7 }
95/99
Análise de Algoritmos
Exercícios Escritos

d)
1 public static boolean ehPalindromo( String exp ) {
2 int n = exp.length();
3 for ( int i = 0; i < n/2; i++ ) {
4 // considere que o corpo desse if nunca será executado
5 if ( exp.charAt(i) != exp.charAt(t-1-i) ) {
6 return false;
7 }
8 }
9 return true;
}
e)
1 for ( int i = 0; i < n; i++ ) {
2 for ( int j = 0; j < n; j++ ) {
3 System.out.println( i * j );
4 }
5 }
96/99
Análise de Algoritmos
Exercícios Escritos
f)
1 for ( int i = 0; i < 10; i++ ) {
2 for ( int j = 0; j < n; j++ ) {
3 System.out.println( i * j );
4 }
5 }
g)
1 for ( int i = 0; i < n; i++ ) {
2 for ( int j = 0; j < 20; j++ ) {
3 System.out.println( i * j );
4 }
5 }
h)
1 for ( int i = 1; i < 50; i++ ) {
2 for ( int j = 1; j < 50; j++ ) {
3 System.out.println( i * j );
4 }
5 }
97/99
Análise de Algoritmos
Exercícios Escritos

i)
1 for ( int i = 0; i < n; i++ ) {
2 for ( int j = 0; j < n; j++ ) {
3 for ( int k = 0; k < n; k++ ) {
4 System.out.println( i * j + k );
5 }
6 }
7 }

j)
1 for ( int i = 0; i < n; i++ ) {
2 for ( int j = 5; j < 20; j++ ) {
3 for ( int k = 0; k < n; k++ ) {
4 System.out.println( i * j + k );
5 }
6 }
7 }
98/99
Análise de Algoritmos
Exercícios Escritos
k)
1 for ( int i = 0; i <= n; i++ ) {
2 for ( int j = 0; j < n; j++ ) {
3 System.out.println( i * j + 3 );
4 }
5 for ( int k = 1; k <= n; k++ ) {
6 System.out.println( i * k * k );
7 }
8 }
l)
1 for ( int i = 1; i <= 10; i++ ) {
2 for ( int j = 0; j < n; j++ ) {
3 System.out.println( i * j + 3 );
4 }
5 for ( int k = n; k >= 0; k-- ) {
6 System.out.println( i * k * k );
7 }
8 }
99/99
Bibliografia

SEDGEWICK, R.; WAYNE, K. Algorithms. 4. ed. Boston:


Pearson Education, 2011. 955 p.
GOODRICHM M. T.; TAMASSIA, R. Estruturas de Dados &
Algoritmos em Java. Porto Alegre: Bookman, 2013. 700 p.
CORMEN, T. H.; LEISERSON, C. E.; RIVEST, R. L.; STEIN, C.
Algoritmos – Teoria e Prática. 3. ed. São Paulo: GEN LTC,
2012. 1292 p.

Você também pode gostar