Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 13 Criado por Frederick H....

34
Pearson Education Slide 1

Transcript of Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 13 Criado por Frederick H....

Pearson Education Slide 1

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 23

Acompanhando a Função power()Painel 13.4

página 389

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 29

Pseudocódigo para Busca BináriaPainel 13.5 página 392

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 31

Execução da Busca BináriaPainel 13.7

página 395

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’