Recursividade Bruno Silva
Conceito de Recursividade Um programa recursivo é um programa que chama a si mesmo, direta ou indiretamente Conceito poderoso Define conjuntos infinitos com comandos finitos Vantagens Redução do tamanho do código fonte Permite descrever algoritmos de forma mais clara e concisa Desvantagens Redução do desempenho de execução devido ao tempo para gerenciamento de chamadas Dificuldades na depuração de programas recursivos, especialmente se a recursão for muito profunda
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.
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
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.
Implementação da Recursividade Usa-se uma pilha para armazenar os dados usados em cada chamada de um procedimento / função que não terminou Todos os dados não globais são armazenados na pilha, informando o resultado corrente Quando uma ativação anterior prossegue, os dados da pilha são recuperados
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
Exemplo – Função Fatorial Definição de uma Função Fatorial Não Recursiva: N! = 1, para N=0; N! = 1 x 2 x 3 x ... x N, para N>=1; Recursiva: N! = N x (N – 1), para N>=1;
Implementação de Fatorial Caso iterativo int factorial( int N ) { int product = 1; for ( int j=1; j<=N; j++ ) { product = product * j; } return product;
Implementação de Fatorial Caso Recursivo /** calcula o fatorial de N. @param n o numero que desejamos calcular o fatorial @return n! – fatorial de n. */ int fatorial(int n) { // Base Case: if (n <= 1) { return 1; } // Recursive Case: // If n > 1 then n! = n * (n-1)! else { return n * fatorial (n-1);
Problema com terminação de Procedimentos Recursivos Procedimentos recursivos introduzem a possibilidade de iterações que podem não terminar: existe a necessidade de considerar o problema de terminação. É fundamental que a chamada recursiva a um procedimento P esteja sujeita a uma condição A, a qual se torna satisfeita em algum momento da computação. Ex.: Se não existisse a condição n=0, quando o procedimento terminaria? Condição de terminação Permite que o procedimento deixe de ser executado O procedimento deve ter pelo menos um caso básico para cada caso recursivo, o que significa a finalização do procedimento
Outro Exemplo - Busca em uma Lista Linear Ordenada Pode-se realizar a busca em um elemento de duas formas: Busca Seqüencial Busca Binária Busca Seqüencial: elementos são pesquisados de acordo com o índice Pior caso: o elemento está no último índice da lista.
Busca Seqüencial Procedure Busca_Sequencial(L: TipoLista; x: TipoItem); Var i: integer; Begin i:=1; while ( L.Item[i]) <> x and i<=L.Ultimo – 1 do i:= i+1; if L.Item[i] = x then Writeln (‘Elemento Encontrado’); else Writeln (‘Elemento Não Encontrado’); End; COMO EXERCICIO ESCREVA ESSE ALGORITMO EM JAVA. E ME MANDE ATÉ O DIA 04/06
Busca Seqüencial A C E H L M P R T Z Procurar por R -8 Comparações! Se eu estivesse procurando o item Z, o número de comparações seria a quantidade de elementos no vetor O ideal seria dividir o vetor pela metade para então procurar (Busca Binária)
Busca Binária Divide seu vetor em duas metades Três condições Se o item for igual ao item que está na metade do vetor, o item foi encontrado Se for menor, procure na primeira metade Se for maior procure na segunda metade
Busca Binária A C E H L M P R T Z Procurar por R I F I F X X 1 2 3 4 5 6 7 8 9 10 A C E H L M P R T Z I F I F X X -2 Comparações! Casos piores: quando os itens estiverem no início do vetor. Nesse caso, seria melhor utilizar busca seqüencial. Mas como saber quando o ítem está no início do vetor?
Busca Binária Procedure Busca_Binária(L: TipoLista; x: TipoItem; Inicio, Fim: integer); Var meio: integer; Begin meio := (inicio + fim) div 2; If fim < inicio then Writeln (‘Elemento Não Enontrado’) Else If (L.Item[meio]) = x then Writeln (‘Elemento está na posição ’ + meio) Else If L.Item[meio] < x then begin inicio := meio +1; Busca_Binaria (L, x, inicio, fim); end else fim := meio - 1; end; End; COMO EXERCICIO ESCREVA ESSE ALGORITMO EM JAVA. E ME MANDE ATÉ O DIA 04/06