Vous êtes sur la page 1sur 27

Algoritmos e Estruturas de Dados I

Recursividade
Pedro O.S. Vaz de Melo

Problema

Implemente uma funo que classifique os elementos


de um vetor em ordem crescente usando o algoritmo
quicksort:
1.
2.
3.

Seja m o elemento na posio central no vetor;


Seja i o ndice do primeiro e j, o ndice do ltimo elemento do vetor;
Enquanto i for menor ou igual a j, faa com que:
a) O valor de i cresa at encontrar um elemento maior que m;
b) O valor de j diminua at encontrar um elemento menor que m;
c) Haja a troca entre os elementos que ocupam as posies i e j.

Problema

Ao final desses passos, a situao do vetor ser a


seguinte:
esquerda da posio central, existem somente
elementos menores do que m;
direita da posio central, existem somente elementos
maiores do que m;

Assim, o problema de ordenar o vetor se reduz ao


problema de ordenar cada uma dessas metades.

Os mesmos passos sero aplicadas repetidas vezes


cada nova metade, at que cada metade contenha um
nico elemento (caso trivial).
3

Problema 2

Considere o exemplo abaixo:


Ordenar {4,1,3,5,2}

Ordenar {2,1}

Ordenar {5,4}

2
1

Ordenar {1}

5
2

Ordenar {2}

4
Ordenar {4}

4
5
Ordenar {5}

Como a natureza dos problemas sempre a mesma


(ordenar um vetor), o mesmo mtodo pode ser usado
para cada subproblema.
4

Anlise do programa

Veja que interessante: a


funo quicksort chama a
si mesma!!!
5

Recursividade

A funo quicksort implementada um exemplo de


funo recursiva: funo que chama a si mesma.
A recursividade uma forma interessante de resolver
problemas por meio da diviso dos problemas em
problemas menores de mesma natureza.
Se a natureza dos subproblemas a mesma do
problema, o mesmo mtodo usado para reduzir o
problema pode ser usado para reduzir os subproblemas
e assim por diante.
Quando devemos parar? Quando alcanarmos um caso
trivial que conhecemos a soluo.

Recursividade

Assim, um processo recursivo para a soluo de um


problema consiste em duas partes:
1. O caso trivial, cuja soluo conhecida;
2. Um mtodo geral que reduz o problema a um ou mais
problemas menores (subproblemas) de mesma natureza.

Muitas funes podem ser definidas recursivamente.


Para isso, preciso identificar as duas partes acima.

Exemplo: fatorial de um nmero e o n-simo termo da


seqncia de Fibonacci.

Funo fatorial

A funo fatorial de um inteiro no negativo pode ser


definida como:

1
n0

n!
n (n 1)! n 0

Esta definio estabelece um processo recursivo para


calcular o fatorial de um inteiro n.

Caso trivial: n=0. Neste caso: n!=1.

Mtodo geral: n x (n-1)!.


8

Funo fatorial

Assim, usando-se este processo recursivo, o clculo de


4!, por exemplo, feito como a seguir:
4! = 4 * 3!
= 4 * (3 * 2!)
= 4 * (3 * (2 * 1!))
= 4 * (3 * (2 * (1 * 0!)))
= 4 * (3 * (2 * (1 * 1)))
= 4 * (3 * (2 * 1))
= 4 * (3 * 2)
=4*6
= 24

Mas como uma funo recursiva como


esta de fato implementada no
computador?
Usando-se o mecanismo conhecido como
Pilha de Execuo!
9

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo
Empilha fatorial(4)

fatorial(4)

-> return 4*fatorial(3)


10

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo
Empilha fatorial(3)

fatorial(3)

-> return 3*fatorial(2)

fatorial(4)

-> return 4*fatorial(3)


11

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo
Empilha fatorial(2)

fatorial(2)

-> return 2*fatorial(1)

fatorial(3)

-> return 3*fatorial(2)

fatorial(4)

-> return 4*fatorial(3)


12

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo
Empilha fatorial(1)

fatorial(1)

-> return 1*fatorial(0)

fatorial(2)

-> return 2*fatorial(1)

fatorial(3)

-> return 3*fatorial(2)

fatorial(4)

-> return 4*fatorial(3)


13

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo
Empilha fatorial(0)
fatorial(0)

-> return 1 (caso trivial)

fatorial(1)

-> return 1*fatorial(0)

fatorial(2)

-> return 2*fatorial(1)

fatorial(3)

-> return 3*fatorial(2)

fatorial(4)

-> return 4*fatorial(3)


14

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo
Desempilha fatorial(0)
fatorial(0)

-> return 1 (caso trivial)

fatorial(1)

-> return 1*fatorial(0)

fatorial(2)

-> return 2*fatorial(1)

fatorial(3)

-> return 3*fatorial(2)

fatorial(4)

-> return 4*fatorial(3)


15

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo
Desempilha fatorial(1)
fatorial(1)

-> return 1*1

fatorial(2)

-> return 2*fatorial(1)

fatorial(3)

-> return 3*fatorial(2)

fatorial(4)

-> return 4*fatorial(3)


16

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo

Desempilha fatorial(2)
fatorial(2)

-> return 2*(1*1)

fatorial(3)

-> return 3*fatorial(2)

fatorial(4)

-> return 4*fatorial(3)


17

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo

Desempilha fatorial(3)
fatorial(3)

-> return 3*(2*1*1)

fatorial(4)

-> return 4*fatorial(3)


18

Funo fatorial

Considere, novamente, o exemplo para 4!:

Pilha de Execuo

Desempilha fatorial(4)
fatorial(4)

-> return 4*(3*2*1*1)


19

Funo fatorial

Considere, novamente, o exemplo para 4!:

Resultado = 24

20

Menor elemento de uma lista

A funo menorElemento de uma lista de n inteiros pode


ser definida como:

menorElemento(lista, i, n) = lista[i],
menor(lista[i], menorElemento(lista,i+1,n)),

se i == n
se i != n

E a funo menor(x,y) retorna o menor nmero entre x e y

Esta definio estabelece um processo recursivo para


calcular o menor nmero de uma lista com n elementos
a partir de uma posio inicial i.

Caso trivial: n=i. Neste caso: o menor da lista o seu


elemento lista[i].

Mtodo geral: menor(lista[i], menorElemento(lista,i+1,n))

21

Menor elemento de uma lista

22

Menor elemento de uma lista

23

Funo Fibonacci

A funo Fibonacci retorna o n-simo nmero da


seqncia: 1, 1, 2, 3, 5, 8, 13, ....

Os dois primeiros termos so iguais a 1 e cada um dos


demais nmeros a soma dos dois nmeros
imediatamente anteriores.

Sendo assim, o n-simo nmero fib(n) dado por:


1
n 1

fib(n)
1
n2
fib(n 2) fib(n 1) n 2

24

Funo Fibonacci

Veja uma implementao recursiva para esta funo:

fib(1)

fib(2)

fib(1)

fib(2)

fib(2)

fib(3)

3
fib(4)

fib(1)

fib(2)

fib(2)

fib(3)

fib(3)

fib(4)

5
8
fib(6)

fib(5)
25

Funo Fibonacci

A funo recursiva para clculo do n-simo termo da


seqncia extremamente ineficiente, uma vez que
recalcula o mesmo valor vrias vezes

Observe agora uma


verso iterativa da
funo fib:

26

Funo Fibonacci

O livro dos autores Brassard e Bradley (Fundamentals


of Algorithmics, 1996, pg. 73) apresenta um quadro
comparativo de tempos de execuo das verses
iterativa e recursiva:
n

10

20

30

50

100

recursivo

8 ms

1s

2 min

21 dias

109 anos

iterativo

0.17 ms

0.33 ms

0.50 ms

0.75 ms

1,50 ms

Portanto: um algoritmo recursivo nem sempre o


melhor caminho para se resolver um problema.
No entanto, a recursividade muitas vezes torna o
algoritmo mais simples.

27

Vous aimerez peut-être aussi