Escolar Documentos
Profissional Documentos
Cultura Documentos
PPG-CC/ ICT-UNIFESP
Correspondência
paulo.gianfelice@unifesp.br Resumo
id Instagran: @paulogianfelice
id Lattes: 2458665575792001 Livro Base: Algoritmos: Teoria e Prática, 2 Estruturas de Dados: Algoritmos, Aná-
1
cel.: 18981250413
Presidente Prudente, SP
lise de Complexidade em Java, C e C++, 3 Estruturas de Dados e Seus Algoritmos,
Outras informações pertinentes
4
Algorithms
Autores: T. H. Cormen; et al., A. F. G. Ascencio e G. S. Araújo, J. L. Szwarcter
sobre o autor podem ser 1 2 3
solicitadas por um dos links
temática. Por sua vez, a análise visa à obtenção de parâmetros que possam avaliar a
das outras pela disposição ou manipulação de seus dados, de modo que, enquanto
abordado, uma vez que, em muitos casos, a solução apropriada para o momento e
os recursos disponíveis é analisada por meio dos pontos positivos e negativos, sem-
onais não são apropriadas pois os conceitos aplicados são fortemente inuenciados
pelo imediatismo, de modo que a análise da solução não são necessárias, tornando
tais como a estruturação básica que consiste em ordenar, fundir, selecionar e inserir
dor continua a crescer, também aumenta o impacto dos métodos básicos abordados
Sumário
Resumo 1
1 Introdução 6
1.1 Algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.4 Recursividade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.6 Eciência . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.1 Notação O . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.2.2 Notação Ω . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.3 Notação Θ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.4 Notação o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.2.5 Notação ω. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3 Relações de Recorrência 22
3.1 Detalhes técnicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
sidera um código real para que os programas possam ser rapidamente colocados em
ção modernas, tal como Python ou R, para que os tipos de dados sejam também
computação como ciência e, de acordo com o livro base (Algoritmos: teoria e prática
de T. H. Cormen; et al.), métodos que vem sendo propostos nos últimos anos.
6
1 Introdução
Na Seção 1.1 é apresentada uma descrição para o que se pode denir como algo-
ritmo, enquanto que na Seção 1.2 é descrito o que é uma estrutura de dados dando
A Seção 1.3 retoma o conceito de algoritmo para denir uma possível apresentação
Finalmente, de certo modo, a Seção 1.6 linka todas as seções anteriores para
tamanho n considerada.
1.1 Algoritmos
nido que toma algum valor ou conjunto de valores como entrada e produz algum
e saída.
Por exemplo, poderia ser necessário ordenar uma sequência de números em ordem
não decrescente. Na prática, esse problema surge com frequência e oferece um solo
padronizadas.
dados única funciona bem para todas as nalidades e, por isso, é importante co-
Dada, por exemplo, a sequência de entrada 31, 41, 59, 26, 41, 58, um algoritmo
de ordenação devolve como saída a sequência 26, 31, 41, 41, 58, 59. Tal sequência
problema.
B) onde
Saída: uma permutação (ou reordenação) de entrada tal que, quando a entrada for
Diz-se que um algoritmo é correto se, para toda instância (ou todos os dados
de entrada), ele parar com a saída correta, neste caso dizemos que um algoritmo
não parar em algumas instâncias de entrada ou poderia parar com uma resposta
Algoritmos são, pelo menos neste texto, descritos através de uma linguagem de
gramação Pascal, por exemplo. Contudo, para facilitar a sua interpretação adota-se
gem.
e o nal de cada bloco são determinados por endentação, isto é, pela posição
um bloco, ele se estende até a última linha seguinte, cuja margem esquerda
se. . . então
se. . . então. . . senão
enquanto. . . faça
para. . . faça
pare
vetores e matrizes são identicados por índices entre colchetes. Por exemplo,
com a 3° coluna.
A referência a registros pode ser também realizada por meio de ponteiros, que
variável utilizada.
comentário.
1.4 Recursividade
tações, e consiste daquele que contém, em sua descrição, uma ou mais chamadas a
9
a si mesmo é dita chamada recursiva que, naturalmente, deve possuir pelo menos
externa.
Um procedimento não recursivo é, pois, aquele em que todas as chamadas são ex-
recursivo correspondente, e além disso, muitas vezes é aparente a relação direta en-
tre um procedimento recursivo e uma prova por indução matemática. Nesses casos,
inteiro n>0 cujo algoritmo recursivo para efetuar esse cálculo encontra-se descrito
a seguir.
função fat(i)
se i ≤ 1 então fat(i) := 1, senão f at(i) := i · f at(i − 1)
o fatorial de n˘1, para n > 0. Por convenção, sabe-se que 0! = 1, para o qual
D entre duas matrizes dadas, A = [ai,j ] e B = [bi,j )], ambas quadradas de dimensão
n. Nesse caso, C e D também possuem dimensão n e seus elementos ci,j e di,j podem
ser calculados, respectivamente, por
n
X
di,j = ai,k + bk,j
k=1
1.6 Eciência
Algoritmos diferentes e criados para resolver o mesmo problema muitas vezes são
muito diferentes em termos de eciência, e tais diferenças podem ser muito mais
Como exemplo, tomando dois algoritmos de ordenação, que serão abordados nas
seções posteriores, sendo o primeiro conhecido como ordenação por inserção (que
denação por inserção normalmente tem um fator constante menor que a ordenação
fatores constantes podem causar um impacto muito menor sobre o tempo de exe-
nação por intercalação por c2 n log2 (n), veremos que, enquanto o fator do tempo
log2 (n), que é muito menor (por exemplo, n = 1000 ⇒ log2 (n) ≈ 10 enquanto que
mente do quanto c1 seja menor que c2 , sempre haverá um ponto de corte além do
Supondo que o computador A execute 101 0 de instruções por segundo (mais ra-
deste livro) e que o computador B execute apenas 107 de instruções por segundo,
assim, o computador A será 1000 vezes mais rápido que o computador B em capa-
lação utilizando uma linguagem de alto nível com um compilador ineciente, sendo
que o código resultante totaliza 50n log2 (n) instruções, para ordenar 107 de núme-
2(107 )2 inst
= 20000seg
1010 inst/seg
Usando um algoritmo cujo tempo de execução cresce mais lentamente, até mesmo
A.
algoritmo, o ganho em precisão em geral não vale o esforço do cálculo. Para en-
mais baixa de um tempo de execução exato são dominados pelos efeitos do próprio
Isso signica que estamos preocupados com o modo como o tempo de execução
toticamente mais eciente será a melhor escolha para todas as entradas, exceto as
muito pequenas.
um algoritmo são denidas em termos de funções cujos domínios são o conjunto dos
números naturais N = {0, 1, 2, ...}, e tais notações são convenientes para descrever
a função do tempo de execução do pior caso, que em geral é denida somente para
de vários modos. Por exemplo, é possível estender a notação ao domínio dos núme-
ros reais ou, como alternativa, restringi-la a um subconjunto dos números naturais,
de alta abstração nas áreas da matemática teórica, como em análise funcional por
funções.
terizam algum outro aspecto dos algoritmos, como a quantidade de espaço que eles
usam, por exemplo, ou até mesmo a funções que absolutamente nada têm a ver
está se referindo.
sua tarefa, e é medido por meio de seu execução. Os resultados obtidos podem ser
não;
2 a dependência de hardwares ; e
3 a quantidade de memória de processamento disponível na máquina.
nicativas para isso são as que contribuem para o tempo de execução do algoritmo,
tal modelo acaba denido como uma função do custo ou tempo. Tal função é con-
Denição 2.1 (Função complexidade) Seja T uma função não negativa que
representa o custo ou o tempo de execução de um algoritmo em função do tamanho
de entrada n de um dado problema. Deni-se como função complexidade a função
T (n) que estabelece a medida do custo ou de tempo necessário para executar o al-
goritmo de um problema de tamanho n.
Veja que T (n) é uma medida, e comumente está associada ao tempo necessário
para executar um algoritmo, por isso, T pode ser denida ainda como uma função
É importante enfatizar que T (n) representa qualquer uma das complexidades (de
tempo ou de custo), no entanto, T (n) refere-se diretamente ao número de vezes que
apresentada na sequência.
Denição 2.2 (Domínio assintótico) Sejam f (n) e g(n) duas funções assinto-
ticamente positivas ou não negativas e distintas. Deni-se como domínio assintótico
da função f (n), a função g(n) quando, existem duas constantes estritamente posi-
tivas c e n0 , tais que, para todo n ≥ n0 ocorrer f (n) ≤ cg(n).
f (n). Por isso, considera-se que toda função tomada para satisfazer essa denição
seja assintoticamente não negativa e essa premissa também se mantém para as ou-
Sobretudo, uma função assintoticamente positiva é uma função positiva para todo
bros f (n) e g(n) sejam assintoticamente positiva ou não negativo, isto é, que
f (n) e g(n) sejam positivas ou não negativas sempre que n for sucientemente
grande. Considerando f (n) e g(n) quaisquer, eventualmente assintoticamente nega-
|f (n)| ≤ c|g(n)|.
De fato!
1
|f (n)| ≤ c|g(n)| ⇒ |n| ≤ c| − n2 | ⇒ n ≤ cn2 ⇒ c ≥
n
De certo modo, a análise assintótica, por meio de alguma das notações que serão
denidas a seguir, deriva da denição 2.2. Na prática, as funções f (n) e g(n) são
plexidades de qualquer caso são todas iguais entre si para cada algoritmo, tanto
igual a 3n será aproximado para n, além disso, como o interesse é restrito a valo-
res assintóticos, termos de menor grau também podem ser desprezados, tal como
representar situações como essas, este é o principal objetivo das notações assintóticas
2.2.1 Notação O
De uma forma simples, a notação O limita assintoticamente uma função por ma-
joração, ou seja, quando temos apenas um limite assintótico superior. Para uma
dada função g(n), denotamos por O[g(n)] (lê-se Ó 'grande' de g de n ou, às vezes,
f (n)
lim = 0.
n→∞ g(n)
n ≥ 3.
Portanto, existem as constantes c, n0 > 0 tais que f (n) é O[g(n)], e elas valem
c=1 e n0 = 3.
Com base no conjunto O[g(n)], uma segunda denição para a notação O pode ser
Denição 2.4 (Notação O) Dados f (n) e g(n), duas funções não negativas, po-
demos armar que f (n) ∈ O[g(n)] se, e somente se, para qualquer c > 0 e todos os
n ≥ n0 > 0 ocorrer f (n) ≤ cg(n).
De fato! Neste caso temos que g(n) = n2 , e como f (n) = n2 /3 − 3n = (n2 − 9n)/3,
tem-se
f (n) n2 − 9n 1 + 9n−1 1
lim = lim 2
= lim = > 0.
n→∞ g(n) n→∞ 3n n→∞ 3 3
n2 − 9n
f (n) = ≤ cn2 = cg(n) ⇔ n − 9 ≤ 3cn ⇔ n ≤ 3cn + 9
3
2.2.2 Notação Ω
uma função, a notação Ω nos dá um limite assintótico inferior. Para uma determi-
nada função g(n), denotamos por Ω[g(n)] (lê-se ômega grande de g de n ou, às
vezes, ômega de g de n) o conjunto de funções
dizer que, não importando qual entrada especíca de tamanho n seja escolhida para
cada valor de n, o tempo de execução para essa entrada é no mínimo uma constante
vezes g(n), para n sucientemente grande.
De modo equivalente, estamos dando um limite inferior para o tempo de execução
g(n)
lim = 0.
n→∞ f (n)
Exemplo 2.5 Sejam f (n) = 3n2 e g(n) = log (n). Então existem as constantes
c, n0 > 0 tais que f (n) é Ω[g(n)].
g(n) log n
lim = lim = 0.
n→∞ f (n) n→∞ 3n2
então, pelo teorema do confronto, sejam g1 (n) = 0 e g2 (n) = n, tais que, para todo
0 = lim 0 < lim log n ≤ lim 3n2 ⇒ lim g1 (n) < lim g(n) ≤ lim g2 (n).
n→∞ n→∞ n→∞ n→∞ n→∞ n→∞
Daí, como
então
g(n) log n
0 < lim = lim ≤0
n→∞ f (n) n→∞ 3n2
18
Logo, g(n)/f (n) é limitada em ambos os lados por 0, e então pela denição 2.5 g(n)
é dominada assintoticamente por f (n) e podemos armar que f (n) ∈ Ω[g(n)] e que
existem um c, n0 > 0 tais que para todos os n ≥ n0 ocorre f (n) ≥ cg(n).
2
Portanto, dadas f (n) = 3n e g(n) = log (n), para as constantes c = n0 = 1
Denição 2.6 (Notação Ω) Dados f (n) e g(n), duas funções não negativas, po-
demos armar que f (n) ∈ Ω[g(n)] se, e somente se, para qualquer c > 0 e todos os
n ≥ n0 > 0 ocorrer f (n) ≥ cg(n).
Exemplo 2.6 Seja f (n) = n2 /2 − 3n. Então f (n) é Ω(n2 ) para quaisquer c > 1/7
com n0 = 7.
n2 n2 n2 1
f (n) = − 3n ≥ cn2 = cg(n) ⇔ ≥ cn2 + 3n > cn2 ⇔ > cn2 ⇔ c <
2 2 2 2
que c = 1/k , para todos os k > 2 e inteiros, verica-se que c = 1/3 ⇒ n0 = 18,
Exemplo 2.7 Sejam f (n) = 2n3 + 3n2 + n e g(n) = n3 . Então existem as cons-
tantes c, n0 > 0 tais que 2n3 + 3n2 + n = O(n3 ).
De fato!
c ≤ 2 + 3n−1 + n−2 = 2 + 3 + 1 = 6 ⇔ c ≤ 6.
Portanto, para qualquer 0 < c ≤ 6, verica-se que 2n3 + 3n2 + n ≥ cn3 , para todo
2.2.3 Notação Θ
A notação Θ é utilizada para dar um limite assintótico rme sobre uma função.
quando f (n) ̸= g(n) apenas um dos casos descritos pelas denições 2.4 e 2.5 é
Denição 2.7 (Notação Θ) Dados f (n) e g(n), duas funções não negativas, po-
demos armar que f (n) ∈ Θ[g(n)] se, e somente se, para qualquer c1 , c2 , n0 > 0,
com c1 ̸= c2 e todos os n ≥ n0 > 0 ocorrer c1 g(n) ≤ f (n) ≤ c2 g(n).
Como nas notações anteriores, também podemos escrever f (n) = Θ[g(n)] para
Consideremos, por exemplo, qualquer função quadrática f (n) = an2 +bn+c, onde
a, b e c são constantes quais quer em R e a restrição a > 0. Descartando os termos
2
de ordem mais baixa e ignorando a constante, produzimos f (n) = Θ(n ), mas, for-
mente, que f (n) ≥ c2 g(n) ⇒ f (n) = Ω[g(n)] e f (n) ≤ c2 g(n) ⇒ f (n) = O[g(n)] ou
2
seja, que c1 g(n) ≤ f (n) ≤ c2 g(n) ⇒ f (n) = Θ(n ).
por f (n) está contida em [c1 g(n), c2 g(n)] exceto, possivelmente, para todos os n à
20
2.2.4 Notação o
o limite assintótico superior fornecido pela notação O pode ser ou não assintotica-
mente justo.
como polinômios por um grau, sendo assintoticamente justo o polinômio f1 (n) por
2
ser de mesma ordem que o polinômio g(n) = n .
superior que não é assintoticamente justo e que, formalmente, tem denição que,
f (n)
lim =0
n→∞ g(n)
o que permite armar que a convergência forte das notações O e o são as mes-
mas, mas em o se obtém uma convergência forte restrita à cg(n), de modo que
f (n) ≤ cg(n) ⇒ f (n) = O[g(n)] e f (n) < cg(n) ⇒ f (n) = O[g(n)].
Note que, pela denição do conjunto mostrado acima, é redundante a arma-
ção de que a desigualdade 0 ≤ f (n) < cg(n) seja a condição para que elementos
f (n) ∈ o[g(n)] ⊆ R∗+ , pois sef (n) ∈ R∗+ , é evidente que f (n) ≥ 0. Entretanto,
tal redundância surge como um pretexto para estabelecer a condição análoga a
0 ≤ f (n) < cg(n) como 0 ≤ c1 g(n) ≤ f (n) < c2 h(n), para interpretarmos o con-
Nas condições que denem este conjunto, vale ressaltar que k, c, n0 ∈ R+ indica
que k, c e n0 não são estritamente positivos mas, a condição n ≥ n0 > 0 destaca
que n0 é estritamente positivo. Além disso, como f (n) ∈ R+ e, como no conjunto
denido no início dessa seção, podemos ter f (n) = 0 de modo que a condição
c′ g(n) ≤ f (n) < ch(n) permite estabelecer que cg(n) > 0, destacando que c e g(n)
21
são estritamente positivos, e que 0 ≤ kg(n) ≤ f (n) com g(n) > 0 implica que
Denição 2.8 (Notação o) Dados f (n) e g(n), duas funções não negativas, po-
demos armar que f (n) ∈ o[g(n)] se, e somente se, para qualquer k ≥ 0 e c, n0 > 0,
com k ̸= c e todos os n ≥ n0 > 0, ocorrer que f (n) ̸∈ Ω[g(n)] e f (n) ∈ O[g(n)] (ou
seja, se simultaneamente ocorrer f (n) ̸= Ω[g(n)] e o caso assintoticamente justo
de f (n) = O[g(n)]), ou seja, que 0 ≤ kg(n) < f (n) e f (n) ≤ cg(n), respectivamente.
De fato!
Primeiramente, vamos mostrar que f (n) = o(n2 ) e para isso devemos mostrar
que f (n) = O(n ), assintoticamente justo (AJ) e com f (n) ̸= Ω(n2 ). Seja então
2
g(n) = n2 , como f (n) ∈ O(n2 ) ⇔ f (n) ≤ cg(n), sobre 3n + 2 ≤ cn2 verica-se que
5n2 .
Agora, para mostrar que f (n) ̸= o(n) basta mostrar que f (n) = Ω(n). Para isso,
mente não justo entre f (n) = 3n + 2 e h(n) = n, isto é, f (n) ∈ O[h(n)] mas não
são AJ.
Portanto, f (n) ̸= o(n), pois as condições necessárias não são satisfeitas. Em par-
2.2.5 Notação ω
Por analogia, a notação ω está para a notação Ω como a notação o está para a
notação O. Usamos a notação ω para denotar um limite inferior que não é assinto-
f (n)
lim = ∞.
n→∞ g(n)
Formalmente, dene-se:
Denição 2.9 (Notação ω) Dados f (n) e g(n), duas funções não negativas, po-
demos armar que f (n) ∈ ω[g(n)] se, e somente se, para qualquer k ≥ 0 e c, n0 > 0,
com k ̸= c e todos os n ≥ n0 > 0, ocorrer que g(n) ̸∈ Ω[f (n)] e g(n) ∈ O[f (n)] (ou
seja, se simultaneamente ocorrer g(n) ̸= Ω[f (n)] e o caso assintoticamente justo
de g(n) = O[f (n)]), ou seja, que 0 ≤ kf (n) < g(n) e g(n) ≤ cf (n), respectivamente.
3 Relações de Recorrência
do mesmo problema.
uma equação ou desigualdade que descreve uma função em termos de seu valor
2/3 para 1/3. Se as etapas de divisão e combinação levarem tempo linear, tal algo-
do tamanho do problema original, uma versão recursiva da busca linear por exem-
o problema original. Cada chamada recursiva levaria tempo constante mais o tempo
das chamadas recursivas que zer, o que produz a recorrência T (n) = T (n−1)+Θ(1).
Este capítulo apresenta três métodos para resolver recorrências, isto é, para obter
isso, será fácil determinar limites assintóticos para muitas recorrências simples. So-
Ocasionalmente veremos recorrências que não são igualdades, porém, mais exata-
mente, desigualdades, como T (n) ≤ 2T (n/2) + Θ(n). Como tal recorrência declara
somente um limite superior para T (n), expressaremos sua solução usando a no-
Esta seção considera algumas funções e notações matemáticas padrões para ex-
tem-se f (m) < f (n) ou (estritamente decrescente) quando para todos os m > n
fi (n) para denotar a função f (n) aplicada iterativamente i vezes a um valor inicial
de n e, formalmente, se f (n) é uma função no domínio dos números reais, para
n, para i=0
f (n) =
f [f (n)], para i≥1
Outro importante conceito que comumente se aplica são os de pisos e tetos para
teto de n).
Deste modo, para qualquer número n
j k l m
⌊n/a⌋ n ⌈n/a⌉ n
= com =
b ab b ab
lam a + (b + 1) jak a − (b + 1)
≤ com ≥
b b b b
Além disso, tais conceitos podem ser ser aplicados simultaneamente para destacar
uma aplicação ou denir outros conceitos, como a aritmética modular, quando para
quociente a/n
a mod n = a − ⌊a/n⌋n
b − a. Escrevemos a ≡
/ b (mod n) se a não é equivalente a b, módulo n.
Sobretudo, negligenciamos certos detalhes técnicos práticos quando enunciamos e
mas de tamanho n/2 e n/2, mas nenhum dos tamanhos é realmente n/2, porque
25
é, na realidade
Θ(1), se n = 1
T (n) = l n m l n m
T +T + Θ(n), se n≥2
2 2
pequeno.
Infelizmente, não há nenhum modo geral para a obtenção das soluções corretas
para recorrências, por isso, arriscar um palpite para uma solução exige experiência
Entretanto, por sorte, podemos usar a heurística para estimar uma solução e tam-
bém as árvores de recursão, que veremos posteriormente, para gerar bons palpites.
As vezes, você pode dar um palpite correto para um limite assintótico para a solução
de uma recorrência mas, por alguma razão, a matemática não consegue funcionar
na indução.
ordem mais baixa quando chegar a um impasse como esse, a matemática frequen-
temente funcionará.
camente mais rápido do que o método da força bruta, e produzirá o algoritmo assin-
seguir.
substituição.
Esse método é poderoso, mas temos que adivinhar a forma da resposta para,
Como exemplo, vamos determinar um limite superior para uma suposta recor-
n > n0 ≥ 0 positivo. Numa situação particular para n/2, o que produz T (n/2) ≤
cn/2 lg(n/2), substituindo na recorrência obtemos
onde, xando que T (n) > 0, a última etapa é válida desde que c≥1 e n0 = 1.
Agora, a indução exige que mostremos que essa solução se mantém válida para as
contorno são adequadas como casos-base para a prova indutiva, mas, nos casos gerais
de contorno.
Às vezes, essa exigência pode gerar problemas, como por exemplo, ao supor como
Isso nos remete a notação assintótica que só exige que provemos que T (n) ≤
cn log(n) para n ≥ n0 , onde n0 é uma constante de nossa escolha. Então, mantendo
Θ(1), para n = 1
T (n) = j n k
2T + n + Θ[n log(n)], para n≥2
2
em cada nível da árvore para obter um conjunto de custos por nível e depois soma-
mos todos os custos por nível para determinar o custo total de todos os níveis da
recursão.
Por exemplo, vejamos como uma árvore de recursão daria um bom palpite para
de um limite superior para a solução. Como sabemos que pisos e tetos normal-
leixo que podemos tolerar), criamos uma árvore de recursão para a recorrência
são inteiros.
Figura 1 Construção de uma árvore de recursão para a recorrência T (n) = 3T (n/4) + cn2 .
28
A parte (a) da gura mostra T (n) como a suposta origem da árvore que, na parte
(b), expandimos para uma árvore equivalente representando a recorrência. O termo
sentada pela expansão de cada nó com custo T (n/4) da parte (b), e o custo para
cia.
Visto que os tamanhos dos subproblemas diminuem por um fator de 4 toda vez
que descemos um nível, a certa altura devemos alcançar uma condição de contorno
quando i = log4 (n). Assim, a árvore tem log4 (n) + 1 níveis nas profundidades
0, 1, 2, . . . , log4 (n).
Em seguida, determinamos o custo em cada nível da árvore. Como cada nível tem
três vezes mais nós que o seu nível anterior, portanto o número de nós na profun-
4 para cada nível que descemos a partir da raiz, cada nó na profundidade i, para
inteira:
2 log4 (n−1)
3 3 3 h i
T (n) = cn + cn2 + 2 2
cn + · · · + cn2 + Θ nlog4 (3) =
16 16 16
h i log4X(n−1)
3
i
= Θ nlog4 (3) + cn2 =
i=0
16
h i (3/16 − 1)log4 (n)
= Θ nlog4 (3) + cn2 (E1)
3/16 − 1
Esta última fórmula parece um pouco confusa até percebermos que, mais uma
vez, é possível tirar proveito de um certo desleixo e usar uma série geométrica
h i log4X(n−1)
3
i h i X ∞
3
i
T (n) = Θ nlog4 (3) + cn2 < Θ nlog4 (3) + cn2 =
i=0
16 i=0
16
h i 1 h i 16
= Θ nlog4 (3) + cn2 = Θ nlog4 (3) + cn2 = Θ(n2 )
1 − 3/16 13
e, pela equação (E1), a soma desses coecientes é limitada na parte superior pela
constante 16/13. Visto que a contribuição da raiz para o custo total é cn2 , a raiz
contribui com uma fração constante do custo total, em outras palavras, o custo da
ricaremos à frente), ele deve ser um limite justo. A primeira chamada recursiva
contribui com o custo Θ(n2), então n2 deve ser um limite inferior para a recorrên-
cia.
Agora podemos usar o método de substituição para vericar que nosso palpite
era correto, isto é, queT (n) = O(n2 ) é um limite superior para a recorrência
jnk j n k2 n 2 3 2
T (n) ≤ 3T ( ) + cn2 ≤ 3d + cn2 ≤ 3d + cn2 ≤ dn + cn2 ≤
4 4 4 16
≤ dn2
de que uma solução para uma recorrência é correta, às vezes, é difícil apresentar um
bom palpite. Traçar uma árvore de recursão é um modo direto para dar um bom
Para utilizar o método mestre você terá de memorizar três casos, mas poderá
resolver muitas recorrências com grande facilidade, muitas vezes sem se munir de
aparatos algébricos e abstratos. O método fornece uma receita para resolver re-
corrências da forma T (n) = aT (n/b) + f (n), onde a≥1 e b>1 são constantes e
está bem denida porque n/b poderia não ser um inteiro. Porém, substituir cada
um dos a termos T (n/b) por T (⌊n/b⌋) ou T (⌈n/b⌉) não afetará o comportamento
assintótico da recorrência, como encontra-se provado em Cormen; et al. (seção 4.3).
Teorema 3.1 (Teorema mestre) Sejam a ≥ 1 e b > 1 constantes, seja f (n) uma
função e seja T (n) denida no domínio dos números inteiros não negativos pela
recorrência T (n) = aT (n/b) + f (n), onde interpretamos que n/b signica ⌊n/b⌋ ou
30
Θ nlogb (a) .
O teorema mestre expõe o signicado de que, em cada um dos três casos, com-
paramos a função f (n) com a função nlogb (a) e, intuitivamente, a maior das duas
Se, como no caso 1, a função nlogb (a) for a maior, então a solução é T (n) =
Θ[nlogb (a) ]. Se, como no caso 3, a função f (n) for a maior, então a solução é T (n) =
Θ[f (n)] e se, como no caso 2, as duas funções tiverem o mesmo tamanho, multiplica-
log (a) log(n)
mos por um fator logarítmico e a solução é T (n) = Θ n b = Θ[f (n)lg(n)].
logb (a)
Além disso, no primeiro caso, f (n) não só tem de ser menor que n , mas deve
logb (a)
ser polinomialmente menor, isto é, f (n) deve ser assintoticamente menor que n
por um fator n para alguma constante ϵ > 0. No terceiro caso, f (n) não apenas
logb (a)
deve ser maior que n , ela tem de ser polinomialmente maior e, além disso, sa-
Observe que os três casos não abrangem todas as possibilidades para f (n). No
logb (a)
entanto, existe uma lacuna entre os casos 1 e 2 quando f (n) é menor que n ,
casos 2 e 3 quando f (n) é maior que nlogb (a) , mas não polinomialmente maior.
caso 3 deixar de ser válida, o método mestre não poderá ser usado para resolver a
recorrência.
Exemplo 3.2 Considere T (n) = T (2n/3) + 1. Como a = 1, bh= 3/2, f (n) i =1e
n = n = 1, aplica-se o caso 2 do teorema, pois f (n) = Θ n
log3/2 (1) 0 log3/2 (1)
= Θ(1).
Portanto, a solução para a recorrência dada é T (n) = Θ[log(n)].
Exemplo 3.4 Considere T (n) = T (n/2)+n lg(n). Neste caso, mesmo que na forma
apropriada, a recorrência dada não é da forma apropriada. Veja que, com a =
b = 2, f (n) = n lg(n) e nlogb (a) = nlog2 (2) = n, verica-se que f (n) = n lg(n) é
assintoticamente maior do que nlogb (a) = n, mas não o é polinomialmente. Para
todos as constantes ϵ > 0 a razão
f (n) n lg(n)
= log (a) = n
nlogb (a) n b