Upload
dinhduong
View
216
Download
0
Embed Size (px)
Citation preview
2
RecursividadeRecursividade
● A recursão é uma técnica que define um problema em termos de uma ou mais versões menores deste mesmo problema.
● É um princípio que permite obter a solução de um problema a partir do próprio problema.
● Exemplos– Dois espelhos são apontados um para o outro,
– Caracóis, girassóis, folha de algumas árvores
5
Triângulo de Sierpinski Triângulo de Sierpinski● Figura geométrica obtida através de um processo recursivo
6
Triângulo de Sierpinski Triângulo de Sierpinski● Algoritmo
1. Comece com qualquer triângulo em um plano. O triângulo de Sierpinski canônico utilizava um triângulo equilátero (figura a.).
2. Encolha o triângulo pela metade (cada lado deve ter metade do tamanho original), faça três copias, e posicione cada triângulo de maneira que encoste nos outros dois em um canto (figura b.).
3. Repita o passo 2 para cada figura obtida, indefinidamente (a partir da figura c.).
7
Estrutura recursivaEstrutura recursiva
● Diz-se que uma estrutura é recursiva se a forma do todo se repete na forma das partes.
8
Função recursivaFunção recursiva
● Uma função recursiva é a capacidade de uma função chamar a própria função.– Exemplo (fatorial)
n! = n(n1)!
● Quando uma função recursiva chama a si mesma, uma nova cópia da função passa a ser executada.
– Os parâmetros locais da segunda cópia são independentes dos parâmetros locais da primeira.
– Exemplos● Números naturais, função fatorial, árvores
9
TiposTipos
● Recursão direta ou simples– Quando a função recursiva chama a si mesma
diretamente.
● Recursão indireta ou composto – Quando a função chama outra função, e esta, por
sua vez chama a primeira.
10
Torres de HanóiTorres de Hanói● Quebra-cabeça inventado no ano de 1883, pelo
matemático Eduard Lucas.
● Objetivo
– Transferir os oito discos que formam a torre para um dos dois bastões vazios, repeitando as seguintes regras:
● Mover apenas um único disco de cada vez;● Nunca colocar um disco maior sobre um disco menor;● Cada disco só pode ser colocado em uma das três hastes.
12
Solução recursivaSolução recursiva● Para resolver um jogo onde precisamos mover n
discos, considerando n > 1, podemos executar os seguintes passos:– Mova n-1 discos para o “pino de trabalho”.
– Mova o n-ésimo pino (o maior de todos) do “pino origem” para o “pino destino”.
– Em seguida resolva o problema da “Torre de Hanói” para os n-1 discos dispostos no “pino de trabalho”, movendo-os para o “pino destino” utilizando o mesmo princípio.
13
Jogo com 3 discosJogo com 3 discos
● Passo 1● Transferência de n-1 discos do “pino origem” para o
“pino de trabalho. – Nesta caso, “pino destino” atua como auxiliar.
– Movimento 1● Pino Origem → Pino Destino
16
Jogo com 3 discosJogo com 3 discos
● Passo 2● Transferência do maior disco do “pino origem” para o
“pino destino”
– Movimento 4● Pino Origem-> Pino Destino
17
Jogo com 3 discosJogo com 3 discos
● Passo 3– Transferência dos n-1 discos do “pino de trabalho”
para o “pino destino”. ● Desta vez, o “pino de origem” atua como área de
armazenamento auxiliar
– Movimento 5● Pino Trabalho-> Pino Origem
20
FibonacciFibonacci
● Caso base
Fib(0) = 1 se n = 0
Fib(1) = 1 se n = 1
● Recursão
Fib(n) = Fib(n-2)+Fib(n-1) se n > 1
21
Estrutura de uma recursãoEstrutura de uma recursão
● Função(lista de parâmetros)– Caso base (Condição de parada)
● Teste de término de recursão– Se teste ok, retorna aqui
● Pode existir mais de um caso base.
– Caso recursivo (Regra geral) ● É a alma da recursão● Permite ao programador redefinir o problema para um que
se aproxime mais do caso base
22
Condição de paradaCondição de parada
● Em funções recursivas pode ocorrer um problema de terminação do programa,– Como um loop interminável ou infinito
● Para não gerar uma recursão infinita, é necessário criar uma condição de parada,– Ela vai dizer quando a função deverá parar de
chamar instâncias dela
23
Passo básicosPasso básicos
1.Inicializar o algoritmo.
● Comece com um ponto de partida, normalmente é passado por parâmetro;
2. Verificar se o valor avaliado corresponde ao caso base;
3. Redefine a resposta em um subproblema menor;
4. Rode o algoritmo no subproblema definido;
5. Combina o resultado para formular a resposta;
6. Devolve um resultado.
24
FatorialFatorial
n! = n.(n – 1).(n – 2). … .1
int fatorial(int n){ int fat = n; while(n>1){
fat=fat*--n;}
return fat;}
25
FatorialFatorial
● Recursiva
int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
n! =1, se n=0 n(n-1)!, se n>0
26
FatorialFatorial● Exemplo 4!
fatorial(4)int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*fatorial(3)
n! =1, se n=0 n(n-1)!, se n>0
27
FatorialFatorial● Exemplo 4!
fatorial(4)int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*fatorial(3)
3*fatorial(2)
n! =1, se n=0 n(n-1)!, se n>0
28
FatorialFatorial● Exemplo 4!
fatorial(4)int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*fatorial(3)
3*fatorial(2)
2*fatorial(1)
n! =1, se n=0 n(n-1)!, se n>0
29
FatorialFatorial● Exemplo 4!
fatorial(4)int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*fatorial(3)
3*fatorial(2)
2*fatorial(1)
1*fatorial(0)
n! =1, se n=0 n(n-1)!, se n>0
30
FatorialFatorial● Exemplo 4!
fatorial(4)int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*fatorial(3)
3*fatorial(2)
2*fatorial(1)
1*fatorial(0)
1
n! =1, se n=0 n(n-1)!, se n>0
31
FatorialFatorial● Exemplo 4!
fatorial(4)int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*fatorial(3)
3*fatorial(2)
2*fatorial(1)
1*fatorial(0)
1
n! =1, se n=0 n(n-1)!, se n>0
32
FatorialFatorial● Exemplo 4!
fatorial(4)int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*fatorial(3)
3*fatorial(2)
2*fatorial(1)
1*1
n! =1, se n=0 n(n-1)!, se n>0
33
FatorialFatorial● Exemplo 4!
fatorial(4)int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*fatorial(3)
3*fatorial(2)
2*1
n! =1, se n=0 n(n-1)!, se n>0
34
FatorialFatorial● Exemplo 4!
fatorial(4)int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*fatorial(3)
3*2
n! =1, se n=0 n(n-1)!, se n>0
35
FatorialFatorial● Exemplo 4!
n! =1, se n=0 n(n-1)!, se n>0
fatorial(4)=int fatorial (int n){ if(n==0) return 1; return n*fatorial(n-1); }
4*6=24
36
Algoritmo de EuclidesAlgoritmo de Euclides
mdc(a: inteiro; b: inteiro): inteiroinício se b = 0 então return a senão return mdc(b, a mod b) fim-sefim-função
37
Recursividade indiretaAlgoritmo de EuclidesRecursividade indiretaAlgoritmo de Euclides
int mdc1(int valorA, int valorB){ printf("\nMDC 1\n"); if(!valorB) return valorA; else return mdc2(valorB, valorA%valorB);}
int mdc2(int valorA, int valorB){ printf("\nMDC 2\n"); if(!valorB) return valorA; else return mdc1(valorB, valorA%valorB);}
38
Recursividade indiretaAlgoritmo de EuclidesRecursividade indiretaAlgoritmo de Euclides
mdc2(valorB, valorA%valorB)
mdc1(valorB, valorA%valorB)
mdc1
mdc2
39
VantagensVantagens
● Soluções recursivas são, geralmente, mais elegantes que suas contrapartes iterativas.
● Uma função recursiva é menor que sua versão iterativa.
40
DesvantagensDesvantagens
● Recursão é lenta:
– Ao chamar uma função, precisamos copiar os parâmetros e inicializar as variáveis. Isso demanda tempo.
● Recursões grandes consomem uma grande quantidade de memória,
– pois é necessário guardar o estado das funções que estão esperando a próxima retornar
● Um deslize na definição da condição de parada pode fazer seu programa chamar a função infinitamente.
– Sempre se assegure que há uma condição de parada