Recursividade - PowerPoint PPT Presentation

1 / 40
About This Presentation
Title:

Recursividade

Description:

Title: Apresenta o do PowerPoint Author: add06 Last modified by: add06 Created Date: 8/22/2005 12:11:02 PM Document presentation format: Apresenta o na tela – PowerPoint PPT presentation

Number of Views:47
Avg rating:3.0/5.0
Slides: 41
Provided by: add97
Category:

less

Transcript and Presenter's Notes

Title: Recursividade


1
Recursividade
Inhaúma Neves Ferraz Departamento de Ciência da
Computação Universidade Federal
Fluminense ferraz_at_ic.uff.br
2
Objetos e Procedimentos Recursivos
  • Um objeto é dito recursivo se consiste
    parcialmente em si mesmo ou é definido em termos
    de si mesmo.
  • Procedimentos recursivos podem ser processadas
    por procedimentos não recursivos simulando a
    recursão.

3
Eventos que ocorrem no uso de Procedimentos
  • Na chamada do procedimento
  • Passagem dos argumentos
  • Alocação e inicialização das variáveis locais
  • Transferência do controle para a função
    (endereço de retorno)
  •  
  • No retorno do procedimento
  • Recuperação do endereço de retorno
  • Liberação da área de dados
  • Desvio para o endereço de retorno
  •  

4
Chamadas de procedimentos (não recursivos)
5
Implementação de procedimentos recursivos
  • Procedimentos recursivos só podem ser
    implementados em alto nível de abstração.
  • As máquinas não executam procedimentos
    recursivos.
  • Cabe ao software simular procedimentos
    recursivos.

6
Simulação de Procedimentos Recursivos
  • A simulação de recursão utilizará uma pilha com
    os seguintes atributos gravados
  • Parâmetros
  • Variáveis
  • Valor da função (se for o caso)
  • Endereço de retorno

7
Chamadas recursivas de funções
8
Exemplo de Procedimentos Recursivos
  • Cálculo do fatorial de um inteiro
  • Série de Fibbonacci
  • Torres de Hanói

9
Cálculo do fatorial de um inteiro
  • public class Factorial
  • public static void main(String args)
  • int input Integer.parseInt(args0)
  • double result factorial(input)
    System.out.println(result)
  • public static double factorial(int x)
  • if (xlt0) return 0.0
  • else if (x0) return 1.0
  • else return xfactorial(x-1)

10
Série de Fibbonacci
  • public static int fib(int n)
  • int x,y
  • if (n lt 1) return 1
  • else
  • x fib(n-1)
  • y fib(n-2)
  • return x y

11
Torres de Hanói
  • Denote os pinos por A, B, C
  • Seja n o número total de discos
  • Numere os discos de 1 (menor, no topo da pilha)
    até n (maior, base da pilha)
  • Para mover n discos do pino A para o pino B
  • Mova n-1 discos de A para C. Isto faz com que o
    disco n fique isolado no pino A
  • Mova o disco n de A para B
  • Mova n-1 discos de C para B de maneira que eles
    fiquem em cima do disco n

12
Exemplo
13
Algoritmo do Fatorial
  • fact(n) n fact(n - 1)
  • se no
  • então
  • fact(0) 1
  • senão
  • x n-1
  • y fact(x)
  • fact(n) n y
  • fim do se

14
Exemplo de uso de pilha
x n-1 y fact(x) fact(n) n y
15
Simulação de Recursão
16
Programa simulador de recursão (1)
  • Para criar um programa que simule a recursão
    deve-se partir do programa recursivo e executar 3
    alterações
  • Alteração inicial
  • Substituição de cada chamada recursiva por um
    conjunto de instruções
  • Substituição de cada retorno da função por um
    conjunto de instruções

17
Programa simulador de recursão (2)
  • O programa assim obtido será uma simulação não
    recursiva do programa recursivo.
  • Em geral o programa assim obtido não é um
    programa bem estruturado e que, freqüentemente,
    pode ser aperfeiçoado por refinamentos
    subseqüentes.

18
Alteração inicial
  1. Declarar uma pilha e inicializá-la como vazia
  2. Associar um rótulo ao primeiro comando executável
  3. Atribuir aos dados correntes os valores adequados

19
Chamadas recursivas
  1. Criar o i-ésimo rótulo Li (ou label_i)
  2. Quando os argumentos da chamada do procedimentos
    forem expressões calcular o valor das expressões
    e atribuir estes valores aos parâmetros formais
  3. Empilhar os parâmetros, as variáveis locais e o
    endereço de retorno i
  4. Atualizar os valores dos parâmetros para o
    prosseguimento do programa
  5. Executar um desvio incondicional para o rótulo do
    início do procedimento
  6. Associar o rótulo criado no item (ou regra) 4 ao
    comando subseqüente ao desvio incondicional

20
Substituição do return
  1. Retornar se a pilha estiver vazia
  2. Desempilhar os parâmetros, variáveis locais e
    endereço de retorno
  3. Se o procedimento for uma função avaliar as
    expressões que se seguem ao return e empilhar o
    resultado
  4. Executar um desvio condicional para o rótulo
    especificado no endereço de retorno corrente

21
Modelos de geração de programas não recursivos
simulando programas recursivos
  • Modelo de alteração inicial
  • Modelo de chamada recursiva
  • Modelo de retorno de chamada recursiva

22
Alteração Inicial
  • / Passo 1 Pilha vazia /
  • s.top MENOS_UM
  • / inicialização de área vazia /
  • currarea.x 0 / por exemplo /
  • currarea.y / por exemplo /
  • currarea.retaddr 0
  • / empilhar a área vazia /
  • push(s,currarea)
  •  / Passo 3 Atribuir aos parametros e endereço
    de retorno os valores adequados /
  • currarea.param n / por exemplo /
  • currarea.retaddr 1 / 1 para retornar a main.
    2 para recursão /
  •  start / Passo 2 associar rótulo inicial ao
    primeiro comando executável /

23
Chamada Recursiva
  • / simulação de chamada recursiva /
  • / Passo 6 empilhamento /
  • push(s,currarea)
  • / Passo 7 atualização dos valores dos
    parâmetros /
  • currarea.x ... / por exemplo /
  • .
  • .
  • currarea.retaddr i
  • / Passo 8 desvio incondicional para o rótulo
    inicial /
  • goto start
  • label_i / Passos 4 e 9 rótulo associado ao
    comando subseqüente ao desvio /

24
Retorno de função
  • / simulação de return /
  • / Passo 11 desempilhar /
  • i currarea.retaddr
  • pop(s,currarea)
  • / Passo 13 desvio condicional para o endereço
    de retorno /
  • switch (i)
  • case 1 goto label1 / tantos casos
    quantos forem as chamadas recursivas 1 /
  • .
  • .
  • case m goto label2
  • / end switch /
  • / end if (currarea.param 0) /

25
Exemplos
  • Serão apresentados dois problemas clássicos de
    recursão
  • cálculo do fatorial de um inteiro
  • problema conhecido como Torres de Hanói

26
Torres de Hanói
27
Passagem de 4 discos do pino A para o pino C
28
(No Transcript)
29
Chamadas de funções (não recursivas)
30
Chamadas recursivas de funções
31
Fatorial recursivo
  • long int fact(int n)
  • int x
  • long int y
  • if (n lt 0)
  • printf("parâmetro negativo d\n",n)
  • exit(1)
  • / end if /
  •  if (n 0)
  • return (1)
  •  x n-1
  • y fact(x)
  • return(ny)
  • / end fact /

32
Simulação da recursão (1)
  • long int simfact1(int n)
  • // Simulação de fatorial
  • struct dataarea currarea
  • short int i
  • long int result
  • s.top MENOS_UM
  • / inicialização de área vazia /
  • currarea.param 0
  • currarea.x 0
  • currarea.y 0
  • currarea.retaddr 0
  • / empilhar a área vazia /
  • if (push(s,currarea) MENOS_DOIS)
  • printf("Estouro de pilha\n")
  • exit(1)
  • / end if /
  • / Atribuir ao parametro e endereço de retorno
    os valores adequados /
  • currarea.param n

33
Simulação da recursão (2)
  • start /inicio da rotina de simulação de
    fatorial /
  • if (currarea.param 0) / fact(0) /
  • / simulação de return /
  • result 1 / fact(0) 1 /
  • i currarea.retaddr
  • if (pop(s,currarea) MENOS_UM)
  • printf("Pilha vazia\n")
  • / end if /
  • switch (i)
  • case 1 goto label1
  • case 2 goto label2
  • / end switch /
  • / end if (currarea.param 0) /
  •   / currarea.param ! 0 /
  • currarea.x currarea.param - 1
  • / simulação de chamada recursiva /
  • if (push(s,currarea) MENOS_DOIS)
  • printf("Estouro de pilha\n")
  • exit(1)

34
Simulação da recursão (3)
  • label2 / ponto de retorno da chamada recursiva
    /
  • / atribui-se o valor retornado a cuurarea.y
    /
  • currarea.y result
  • / simulação de return(ny) /
  • result currarea.param currarea.y
  • i currarea.retaddr
  • / voltar ao ambiente original /
  • if (pop(s,currarea) MENOS_UM)
  • printf("Pilha vazia\n")
  • / end if /
  • switch (i)
  • case 1 goto label1
  • case 2 goto label2
  • / end switch /
  • label1 / ponto de retorno ao programa
    principal /
  • return (result)
  • / end simfact1 /

35
O programa simulador obtido
  • O programa simulador obtido ( fat_nr01) não tem
    uma boa estrutura.
  • Ele pode, e deve, ser aperfeiçoado por
    refinamentos subseqüentes.
  • Inicialmente será criado o programa fat_nr02.

36
Passagem de fat_nr01 para fat_nr02
  • O fatorial corrente y e o valor corrente x podem
    ser globais não necessitando ser empilhados.
  • Como só há um endereço de retorno de chamada
    recursiva, só há um endereço de retorno, pois o
    retorno ao programa chamador é testado pela
    condição de pilha vazia. Portanto não é preciso
    empilhar endereços de retorno usando desvio
    incondicional

37
Passagem de fat_nr02 para fat_nr03
  • switch(pop(s,currarea)) aparece duas vezes
    e agrupando estas ocorrências pode-se simplificar
    o algoritmo
  • x e currparam nunca são usadas simultaneamente e
    podem ser uma só variável x

38
Passagem de fat_nr03 para fat_nr04
  • O laço criado pelo teste inicial e terminado por
    goto start pode ser substituído por um laço while
  • O laço iniciado por label2 e terminado por
    switch(pop(... pode ser substituído por outro
    laço while

39
Passagem de fat_nr04 para fat_nr05
  • O primeiro laço while empilha 1 a n, sendo 1 no
    topo
  • O segundo laço while multiplica o resultado
    corrente pelo topo da pilha
  • Sabendo disso não é preciso nem empilhar nada

40
Algoritmo recursivo das Torres de Hanói
  • void towers(int n, char from, char to, char aux)
  • / Caso haja um só disco, mova-o e retorne /
  • if (n 1)
  • printf("Mover disco 1 do pino c para o pino
    c\n",
  • from, to)
  • return
  • / end if /
  • / Mover os n-1 discos superiores de A para B
    usando C como auxiliar /
  • towers(n-1,from,aux,to)
  • / Mover o disco restante de A para C /
  • printf("Mover disco d do pino c para o pino
    c\n",
  • n, from, to)
  • / Mover os n-1 discos de B para C usando A como
    auxiliar /
  • towers(n-1,aux,to,from)
  • return
  • / end towers /
Write a Comment
User Comments (0)
About PowerShow.com