1 / 30

Recursividade

Recursividade. Inhaúma Neves Ferraz Departamento de Ciência da Computação Universidade F ederal Fluminense ferraz@ic.uff.br. Objetos e Procedimentos Recursivos. Um objeto é dito recursivo se consiste parcialmente em si mesmo ou é definido em termos de si mesmo.

deanna
Download Presentation

Recursividade

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Recursividade Inhaúma Neves Ferraz Departamento de Ciência da Computação Universidade Federal Fluminense ferraz@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. Chamadas recursivas de funções 1 2 11 3 5 10 14 8 19 17 6 12 15 18 7 16 4 9 13

  9. Exemplo de Procedimentos Recursivos Cálculo do fatorial de um inteiro Série de Fibbonacci Torres de Hanói

  10. Cálculo do fatorial de um inteiro public class Factorial { public static void main(String[] args){ int input = Integer.parseInt(args[0]); double result = factorial(input); System.out.println(result); } public static double factorial(int x){ if (x<0) return 0.0; else if (x==0) return 1.0; else return x*factorial(x-1); } }

  11. Série de Fibonacci public static int fib(int n) { // Série de Fibonacci de ordem 4 int x,y; if (n <= 1) return 1; else { x = fib(n-1); y = fib(n-2); z = fib(n-3); return x + y + z; } }

  12. 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

  13. Exemplo

  14. Algoritmo do Fatorial fact(n) = n * fact(n - 1) se n=o então fact(0) = 1 senão x = n-1 y = fact(x) fact(n) = n * y fim do se

  15. Exemplo de uso de pilha x = n-1 y = fact(x) fact(n) = n * y

  16. Simulação de Recursão

  17. 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

  18. Programa simulador de recursão (2) • O programa assim obtido será uma simulação não recursiva do programa recursivo. • Os laços recursivos serão substituídos por laços até obter uma pilha de recursão vazia • Dentro dos laços uma seleção múltipla (switch..case) governa os retornos e desvios do programa

  19. Alteração inicial • Declarar uma pilha e inicializá-la como vazia • Atribuir aos dados correntes os valores adequados • Criar uma repetição até obter pilha vazia contendo uma seleção múltipla cujo parâmetro é o endereço de retorno da recursão • O primeiro caso da seleção é a condição de término da recursão

  20. Chamadas recursivas • Quando os argumentos da chamada do procedimento forem expressões calcular o valor das expressões e atribuir estes valores aos parâmetros formais • Empilhar os parâmetros, as variáveis locais e o endereço de retorno i • Atualizar os valores dos parâmetros para o prosseguimento do programa

  21. Substituição do return • Desempilhar os parâmetros, variáveis locais e endereço de retorno • Se o procedimento for uma função avaliar as expressões que se seguem ao return e empilhar o resultado

  22. 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

  23. Exemplo • Será apresentado um problema clássico de recursão : • cálculo do fatorial de um inteiro

  24. Fatorial recursivo long int fact(int n) { Long int x; long int y; if (n < 0) { printf("parâmetro negativo: %d\n",n); exit(1); } /* end if */  if (n == 0) return (1); x = n-1; y = fact(x); return(n*y); } /* end fact */

  25. Elemento da pilha de recursão class CFactNode { private: //atributos encapsulados long int value; long int x; long int y; short int retAddr;

  26. Alterações iniciais long int FactSwitch(long int n) { stack<CFactNode> FactStack; long int Result; short int i; short int RetAddr; CFactNode currNode; //Empilha termo vazio para desempilhamento no final do processo FactStack.push(CFactNode(0)); //Atribui aos parâmetros e endereço de retorno os valores adequados currNode.setValue(n); currNode.setRetAddr(4); currNode.setX(0); currNode.setY(0); i = 0;

  27. Estrutura do programa while (FactStack.size()) { switch (i) { case 0: // início do procedimento recursivo { if(currNode.getValue()== 0) //caso básico, Saída da Recursão { } else //entrada normal da recursão { } break; } //end case 0 case 1: // retorno da chamada recursiva { break; } //end case 1 default: // retorno final { return (Result); break; } //end default } //end switch } //end While

  28. Case 0: início do procedimento case 0: // início do procedimento recursivo { if(currNode.getValue()== 0) //caso básico, Saída da Recursão { Result = 1; i = currNode.getRetAddr(); // para aonde vai currNode = FactStack.top(); FactStack.pop(); //Desempilha i = currNode.getRetAddr(); } else //entrada normal da recursão { currNode.setX(currNode.getValue() - 1) ; FactStack.push(currNode); //Empilha o currNode //O novo currNode recebe o Valor n-1 currNode.setValue(currNode.getX()); currNode.setRetAddr(1); //vai para case 1 i = 0; // chamada recursiva } break; } //end case 0

  29. Case 1: retorno da chamada recursiva case 1: // retorno da chamada recursiva { //Parâmetro x recebe o valor de Fact(n-1); currNode.setY(Result); Result = currNode.getValue() * currNode.getY(); i= currNode.getRetAddr(); currNode = FactStack.top(); FactStack.pop(); //chamada recursiva break; } //end case 1

  30. Case Default: retorno final default: // retorno final { return (Result); break; } //end default } //end switch } //end While }

More Related