Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 13 Criado por Frederick H....
Transcript of Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 13 Criado por Frederick H....
Pearson Education Slide 2
Capítulo 13
Criado por Frederick H. Colclough, Colorado Technical University
Recursão
Pearson Education Slide 3
Objetivos de Estudo Funções void Recursivas
Acompanhando uma Chamada Recursiva Recursão infinita e transbordamento
Funções Recursivas que Retornam um Valor
Função power Pensando Recursivamente
Técnicas para projetar recursões Busca Binária
Pearson Education Slide 4
Introdução à Recursão Um função que ‘chama a si própria’
Chama-se recursiva Na definição de função, chama a mesma
função
C++ permite recursão Como a maioria da linguagens modernas Pode ser uma técnica muito útil Há limitações
Pearson Education Slide 5
Funções Recursivas void Dividir e Conquistar
Técnica básica de projeto Quebrar grandes tarefas em subtarefas
Subtarefas podem ser versões menoresda tarefa original!
Quando elas são recursão
Pearson Education Slide 6
Exemplo de Funções Recursivas void
Considere a tarefa: Pesquisa um valor em uma lista
Subtarefa 1: Pesquisa 1a metade da lista Subtarefa 2: Pesquisa 2a metade da lista
As subtarefas são versões menores datarefa original!
Quando isso ocorre, pode ser usada umauma função recursiva
Geralmente o resultado é uma solução ‘elegante’
Pearson Education Slide 7
Funções Recursivas void : Números Verticais
Tarefa: Mostrar números verticalmente,um por linha
Exemplo de chamada:escrevaVertical(1234); Produzirá a saída:1234
Pearson Education Slide 8
Números Verticais: Definição de Recursão
Quebra o problema em dois casos Caso simples: se n<10
Simplesmente escreva o numero n na tela Caso recursivo: Se n>=10, duas
subtarefas:1- Obtenha todos os dígitos exceto o último
2- Obtenha o último dígito Exemplo: argumento 1234:
1a subtarefa mostra 1, 2 e 3 verticalmente 2a subtarefa mostra 4
Pearson Education Slide 9
Definição da Função escrevaVertical
Dado o caso anterior:void escrevaVertical(int n){
if (n < 10) //Caso simplescout << n << endl;
else { //Subtarefa
recursivaescrevaVertica (n/10);cout << (n%10) << endl;
}}
Pearson Education Slide 10
Acompanhando escrevaVertical Exemplo de chamada:
escrevaVertical(123); escrevaVertical (12); (123/10)
escrevaVertical (1); (12/10) cout << 1 << endl; cout << 2 << endl;
cout << 3 << endl; A seta indica a tarefa que a função executa Observe que duas chamadas chamam de novo (recursão)
Última chamada (1) exibe e ‘finaliza’
Pearson Education Slide 11
Recursão – Olhando mais de perto O computador controla as chamadas
recursivas
da seguinte forma: Pára a função atual Precisa saber os resultados da chamada recur-
siva antes de prosseguir Salva toda a informação que precisa
Para ser usada mais tarde Continua a executar a chamada recursiva Quando AQUELA chamada termina, retorna
para terminar o cáculo ‘externo’
Pearson Education Slide 12
Recursão Esquema geral de uma boa definição de função
recursiva: Um ou mais casos onde a função completa
suas tarefas: Fazendo uma ou mais chamadas recursivas
pararesolver versões menores da tarefa original
Chamadas ‘Caso(s) recursivo(s)’ Um ou mais casos onde a função completa
suas tarefas sem chamadas recursivas chamados ‘caso(s) simples’ ou caso(s) de
parada
Pearson Education Slide 13
Recursão Infinita Precisamos chegar a um caso de parada Se isto não acontece recursão infinita
Chamadas recursivas que nunca terminam! Lembre-se do exemplo escrevaVertical:
O caso de parada ocorreu quando chegamosa um número de 1 dígito
Quando a recursão parou
Pearson Education Slide 14
Exemplo de Recursão Infinita
Considere a definição de função alternativa:void novaEscrevaVertical(int n)
{
novaEscrevaVertical(n/10);
cout << (n%10) << endl;
}
Parece bastante ‘razoável’ Faltando o ‘caso de parada’! A recursão nunca pára
Pearson Education Slide 15
Pilhas para Recursão Uma pilha
Estrutura de memória especializada Como uma pilha de pápel
Coloque novos no topo Quando necessário, remova do topo
Estrutura de memória chamada ‘último a entrar/primeiro a sair’
Recursão utiliza pilhas Cada chamada recursiva é colocada em uma
pilha Quando uma estiver completa, a última chamada
é removida da pilha
Pearson Education Slide 16
Transbordamento da pilha O tamanho da pilha é limitado
Memória é finita Cadeias longas de chamadas recursivas
continuamente adicionadas à pilha Se a pilha tenta crescer além dos limites:
Erro de Transbordamento de pilha (Stack overflow)
Recursão Infinita sempre causa esse erro
Pearson Education Slide 17
Recursão Versus Iteração Recursão nem sempre é necessária Nem mesmo permitida em algumas linguagens Qualquer tarefa executada com recursão
pode também ser feita sem ela Não-recursiva: chamada iterativa, usando
loops Recursiva:
Roda mais lentamente e usa mais memória Solução elegante; menos código
Pearson Education Slide 18
Funções Recursivas que Retornam um Valor
Recursão não se limita a funções void Pode retornar valores de quaisquer tipos Mesma técnica, esquema:
1- Um ou mais casos em que o valor retornado écalculado por chamadas recursivas
Devem ser “sub-problemas” menores
2- Um ou mais casos em que o valor retornado é calculado sem chamadas recursivas
Casos de parada
Pearson Education Slide 19
Exemplo de Recursão que Retorna um Valor: Power
Lembre-se da função predefinida pow():result = pow(2.0,3.0);
Retorna 2 elevado à potência de 3 (8.0) Requer dois argumentos tipo double Retorna um valor tipo double
Vamos escrevê-la recursivamente Um exemplo simples
Pearson Education Slide 20
Definição de função para power() int power(int x, int n)
{if (n<0){
cout << “argumento ilegal”;exit(1);
}if (n>0)
return (power(x, n-1)*x);else
return (1);}
Pearson Education Slide 21
Chamando a Função power() Exemplo de chamada: power(2, 0);
retorna 1 power(2, 1);
retorna (power(2, 0) * 2); retorna 1
Valor 1 multiplicado por 2 e retornado a chamada
original
Pearson Education Slide 22
Chamando a Função power() Exemplo maior:
power(2,3); power(2,2)*2
power(2,1)*2 power(2,0)*2
1 Alcança o caso de parada A recursão pára Valores ‘retornados’ para o topo da pilha
Pearson Education Slide 24
Pensando Recursivamente Ignore os detalhes
Esqueça como a pilha trabalha Esqueça a suspensão dos cálculos Sim, isto é um princípio de ‘abstração’! E um princípio de encapsulamento!
Deixe o computador fazer a ‘contabilidade’
Pearson Education Slide 25
Pensando Recursivamente: power Considere a função power() novamente Definição recursiva de power():
power(x, n)
retorna:
power(x, n – 1) * x Apenas assegure-se que a ‘fórmula’ esteja correta E assegure-se que o caso de parada irá
ocorrer
Pearson Education Slide 26
Técnicas para Projetar Recursões Não acompanhe a seqüência recursiva
inteira! Apenas verifique 3 propriedades:
1- Não há recursão infinita
2- Casos de parada retornam valores corretos
3- Casos recursivos retornam valores corretos
Pearson Education Slide 27
Verificação do Projeto de Recursão: power()
Confronte power() contra as 3 propriedades:
1- Não há recursão infinita: 2o argumento diminui em 1 em cada chamada Conseqüentemente deve chegar ao caso de parada
em 1
2- Casos de parada retornam valores corretos: power(x,0) é o caso de parada Retorna 1, o qual é correto para x0
3- Casos recursivos retornam valores corretos: Para n>1, power(x,n) retorna power(x,n-1)*x Valores conectados correto
Pearson Education Slide 28
Busca Binária Função Recursiva para busca em um
vetor Determina SE o item está na lista, e se
estiver: Onde ele está na lista
Assume que o vetor está ordenado Divide a lista ao meio
Determina se o item está na 1a ou 2a metade Então busca novamente só naquela metade
Recursividade (é claro)!
Pearson Education Slide 30
Verificando a Recursão Confronte a busca binária com os critérios:
1- Não há recursão infinita: Cada chamada incrementa first decrementa last Finalmente first será maior que last
2- Casos de parada retornam valores corretos: Se first > last não há elemento entre eles,
assim, key não pode estar lá! Se key == a[mid] Encontrada corretamente!
3- Casos recursivos retornam valores corretos: Se key < a[mid] key na 1a metade – chamada correta Se key > a[mid] key na 2a metade – chamada correta
Pearson Education Slide 32
Eficiência da Busca Binária Extremamente Rápida
Comparada com a busca seqüencial Metade do vetor é eliminada logo no início!
Então um quarto, 1/8, etc. Finalmente elimina a metade com cada
chamada Exemplo:
Vetor de 100 elementos: Busca binária nunca precisará mais do que 7
comparações! Eficiência logarítimica (log n)
Pearson Education Slide 33
Soluções Recursivas Observe que o algorítmo de busca binária
resolve atualmente o problema ‘mais geral’ Tarefa original: projetar uma função de busca
em um vetor inteiro Nossa função : permite pesquisar qualquer
intervalo do vetor Especificando os limites first [primeiro] e last [ultimo]
Isso é normal quando projetamos funções
recursivas
Pearson Education Slide 34
Sumário Reduzir o problema em instâncias menores
do mesmo problema -> solução recursiva O Algorítmo recursivo tem dois casos:
Casos-base ou casos de parada Caso recursivo
Assegure-se: Não há recursão infinita Use os critérios para determinar se a recursão está correta
Três propriedades essenciais Tipicamente resolve o ‘problema mais geral’