11 recursividade em estrutura de dados

Upload: lemurixx

Post on 23-Feb-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    1/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 1

    Algoritmos Recursivos

    Fundamentos

    Trata-se de rotinas recursivas, onde a rotina para resolver determinado problema, divide-se em subproblemas, e para solucionar esses subproblemas solicita a execuo dele mesma,

    ou seja, uma rotina que quando em execuo chama a si prpria para executar mais vezes

    aquela determinada funo dentro dela, sendo ela de forma direta ou indireta, onde

    geralmente, uma rotina recursiva R, formada por um conjunto de comandos C (que nocontm chamadas a R) e uma chamada recursiva a ela prpria (R).

    R[C,R]

    Entretanto, existe uma forma de recurso indireta, onde as rotinas se ligam atravs de

    uma sucesso de chamadas, que acaba retornando primeira chamada efetuada.

    R1 [C1,R2]

    R2 [C2,R3]

    R3 [C3,R4]

    . . .

    Rn[Cn,Rn]

    Uma rotina indiretamente recursiva faz uma chamada a outra rotina K, por exemplo, e

    essa por sua vez faz uma chamada direta ou indireta a R, tornando-se muitas vezes difcil

    de perceb-la em uma simples leitura.

    Uso de Recurso para Soluo de Problemas

    Todo algoritmo deve ser executado em tempo finito, o que significa que aps ter efetuado

    uma tarefa uma determinada quantia de vezes, deve ser parado para no criar um loopinginfinito.

    Para que no exista a execuo infinita de determinada tarefa deve existir uma expresso

    lgica, cuja funo cessar a execuo quando se torna falsa, impedindo que a recurso

    prossiga infinitamente. No caso da rotina recursiva R [C,TR], onde T R indica achamada de R quando T for satisfeito, as tcnicas bsicas so:

    Colocar T em termos de uma funo (x), tal que (x)0 efetua a condio de

    parada;

    Apresentar (x) numa repetio decrescente, tendo x decrescendo a cada chamada

    em R(x) [C,( (x)>0 ) R(x-1)].

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    2/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 2

    Divide-se um problema numa rotina recursiva em:- soluo trivial por definio, no necessitando de recurso para ser

    obtida, sendo parte do problema que pode ser resolvida pelo conjunto de

    comandos C.- soluo geral na essncia, a parte do problema igual ao problema

    original, sendo solucionado atravs de uma chamada recursiva R(x-1).

    Para saber qual a melhor soluo para um problema, se pelo conjunto de instrues C

    ou pela chamada recursiva R(x-1), nesse caso atravs de um teste! A seguir demonstra-se a

    definio de uma funo recursiva para calcular o fatorial de um nmero natural:

    soluo trivial: 0! = 1 {dada por definio}

    soluo geral: n! = n*(n-1)! {requer reaplicao da rotina para (n-1)!}

    Exemplo 1. Considerando (n) = n, ento n=0 sugere uma condio de parada dessemecanismo recursivo, garantindo a finalizao do algoritmo que calcula o fatorial:

    functionfat (n : integer) : integer;

    begin

    ifn=0 thenfat := 1

    else fat := n * fat(n - 1);

    end;

    Em termos matemticos, a recurso acaba sendo uma tcnica que reduz o problema

    atravs de substituies sucessivas a um caso de soluo trivial. Veja o clculo de f(4) a

    seguir:

    fat(4)4*fat(3)4*3*fat(2)4*3*2*fat(1)4*3*2*1*fat(0)4*3*2*1*1

    Problema a resolver Substituies sucessivas Caso de soluo trivial obtido

    Exemplo 2. Considerando Fn = Fn-1 + Fn-2, onde n>2 F0 = F1 = 1, que explica a

    Sequncia de Fibonacci, gerando os termos 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89..., a formarecursiva se d:

    functionfibonacci(N: integer): integer;

    begin

    ifN < 2

    thenfibonacci := 1

    elsefibonacci := fibonacci(N 1) + fibonacci(N 2);

    end;

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    3/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 3

    O Problema das Torres de Hanoi

    Conta lenda, que no mosteiro no alto das montanhas Hanoi havia trs torres, sendo a

    primeira formada por 64 discos empilhados em tamanho decrescente, e acreditava-se quequando terminasse de transferir todos os discos da primeira torre para a terceira, usando a

    segunda, e sem colocar um disco maior sobre um disco menor, o mundo acabaria.

    Num exemplo simplificado com trs torres e com apenas trs discos, o objetivo seria

    transferir os trs discos da torre A para a torre C usando a torre B como auxiliar, sendo que

    somente o primeiro disco de uma torre pode ser deslocado para outro, e nunca um discomaior sobre outro menor.

    Para solucionar o problema das torres de Hanoi com uma recurso, consideremos que n

    discos devem ser transferidos, assim podemos dividir o problema em dois casos mais

    simples que ir mover n discos, sendo o primeiro atravs da soluo trivial (quando umdisco tiver de ser movido da torre A para torre C), e o segundo atravs de soluo geral

    (uma soluo para n discos em termos de n-1).

    Usaremos o exemplo com trs discos para entender a soluo recursiva proposta,admitindo que movemos 2 discos da torre A para a torre B, usando a torre C teramos:

    Depois poderamos mover o disco maior diretamente da torre A para a torre C.

    E por fim, aplicar novamente a soluo recursiva para mover os 2 discos da torre B para atorre C, usando a torre A.

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    4/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 4

    Ento o que fizemos foi:

    Se n=1, ento transfira o disco de A diretamente para C e pare;

    Seno: 1 transfira n-1 discos de A para B usando C como auxiliar; 2 transfira o

    ltimo disco de A para C; 3 transfira n-1 discos de B para C usando A como

    auxiliar.

    Soluo recursiva em Pascal:

    procedureHanoi (n : integer;A, B, C : char);

    begin

    ifn=1 then

    writeln(Mova disco 1 da torre, A, para, C);

    else

    beginHanoi (n-1, A, C, B);

    writeln(Mova disco, n,da torre, A,para,C);Hanoi (n-1, B, A, C);

    end;

    end;

    www.fortalnet.com.br/jogos/hanoi/hanoi.htm

    Quando Aplicar Recurso

    A recurso uma ferramenta que nem sempre pode ser utilizada, pois h problemas

    que tm soluo instantnea com a forma recursiva, enquanto outros so impossveis de

    serem resolvidos dessa maneira, sendo necessria uma anlise prvia do problema paratem certeza da soluo atravs da recursividade, por que a cada chamada recursivatodas as variveis locais so recriadas, ocupando mais tempo e espao.

    Frente a difcil questo de usar a forma recursiva ou iterativa (no recursiva), cabe

    comparar as solues viveis, lembrando que primeiramente um algoritmo tem de ser

    claro, simples e conciso.

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    5/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 5

    Eliminando Recurses de Cauda

    Diz-se que uma rotina apresenta recurso de cauda, se sua chamada for efetuada no

    final do seu cdigo, criando a funo de looping at que a condio de parada a encerre,como no exemplo seguinte:

    functionfat (n : integer) : integer;

    begin looping!!!!!!

    ifn=0 thenfat := 1

    else fat := n * fat(n - 1);

    end;

    Cada vez que executada, e no for satisfeita a chamada fat (n - 1) ativa, fazendo com

    que o controle retorne ao incio da funo e recrie a varivel, que recebe um novo valor.Como exemplo clssico de recurso, este um caso onde a recurso menos eficiente que

    a iterao, pois proporciona uma recurso de cauda.

    A recurso de cauda pode ser substituda ento por uma estrutura de repetio, como noexemplo seguinte, onde ela esteja condicionada expresso de teste usada na verso

    recursiva.

    Fatorial sem recursividade:

    functionfat_iterativo (n : integer) : integer;

    var f : integer;

    beginf := 1;

    whilen>0 do

    begin

    f := f*n;

    n := n-1;

    end;

    fat_iterativo := f;

    end;

    Exerccios com recursividade:

    Exerccio 1.

    Seja uma linguagem hipottica na qual no existem operadores para adio, nem subtrao.

    Sabe-se que nesta linguagem, existe uma funo succ(N) que d o sucessor do nmero N, eexiste tambm uma funo pred(N) que d o predecessor de um nmero N.Usando apenas

    essas funes (succ/pred), defina a funo recursiva Add (x,y), que toma como argumento

    os nmeros naturais x e y, e retorna sua soma. Em seguida mostre como a recurso de

    cauda pode ser eliminada da funo Add (x,y), usando-se um comando de repetio.

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    6/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 6

    AlgoritmoFuno numrico add (x,y)

    Se x=0

    Ento add := ySeno

    Se y=0Ento add:=x

    Seno add:= add(pred(x), succ(y))

    Fim Se

    Fim SenoFim Se

    Fim Funo

    Declare x, y numrico

    Leia xLeia yEscreva add(x, y)

    FimAlgoritmo

    Em Pascal:

    program recexr2;uses crt;

    function add(x,y:integer):integer;

    beginif x=0 then

    add:=yelse

    if y=0 then

    add:=x

    else

    add:=add(pred(x),succ(y));end;

    var x,y:integer;

    beginclrscr;

    writeln('Entre com o primeiro numero:');

    readln(x);

    writeln('Entre com o segundo numero:');readln(y);

    writeln('Soma:',add(x,y));

    end.

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    7/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 7

    Na forma iterativa:

    Algoritmo

    Funo numrico add_iterativo (x,y)Repita enquanto x > 0

    x:= pred(x)y:=succ(y)

    Fim Repita

    add_iterativo:=y

    Fim Funo

    Em Pascal:

    function add_iterativo(x,y:integer):integer;begin

    while x>0 do

    begin

    x:=pred(x);y:=succ(y);

    end;

    add_iterativo:=y;end;

    var x,y:integer;

    beginclrscr;

    writeln('Entre com o primeiro numero:');readln(x);

    writeln('Entre com o segundo numero:');

    readln(y);

    writeln('Soma:',add(x,y));

    end.

    Exerccio 2.

    Faa um programa Pascal que preencha por leitura (do teclado), um vetor de 10 elementos

    reais, imprima os contedos deste vetor, e que tambm imprima o resultado do somatriodos elementos deste vetor, calculado por uma funo recursiva.

    Algoritmo da Funo:

    Funo numrico soma(n)Se n=1

    Ento soma:=v[n]

    Seno soma:= v[n] + soma(n-1)Fim Se

    Fim Algoritmo

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    8/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 8

    Em Pascal:

    program recur2;

    uses crt;var

    v:array [1..10] of integer;

    function soma(n:integer):integer;

    begin

    if n=1 then soma:=v[n]else soma:=v[n]+soma(n-1);

    end;

    begin

    v[1]:=2; v[2]:=4; v[3]:=5; v[4]:=4; v[5]:=5;v[6]:=6; v[7]:=7; v[8]:=8; v[9]:=9; v[10]:=10;clrscr;

    writeln(soma(10));

    end.

    Exerccio 3.

    Recursividade pode ser utilizada para gerar todas as possveis permutaes de um conjuntode smbolos. Por exemplo, existem seis permutaes no conjunto de smbolos A, B e C:

    ABC, ACB, BAC, BCA, CBA e CAB. O conjunto de permutaes de N smbolos gerado

    tomando-se cada smbolo por vez e prefixando-o a todas as permutaes que resultam dos

    N - 1 smbolos restantes. Conseqentemente, permutaes num conjunto de smbolospodem ser especificadas em termos de permutaes num conjunto menor de smbolos.

    Formular um procedimento recursivo e outro iterativo para este problema.

    Algoritmo

    Declare x literal

    Declare c array[1..3] de literal

    Declare a, i, j, k numrico

    Subrotina mostra

    Se n=4

    Ento finalizar programaFim Se

    Escreva c[n], c[j], c[k]

    Escreva c[n], c[k], c[j]

    j:=kk:=n

    mostra(n+1)

    Fim Subrotina

    Leia x

    c[1]:=x

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    9/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 9

    Leia xc[2]:=x

    Leia x

    c[3]:=xj:=2

    k:=3mostra(1)

    Fim Algoritmo

    Em Pascal:

    program todosABC;

    uses crt;var

    x:char;c:array [1..3] of char;a,i,j,k:integer;

    procedure mostra(n:integer); {soluo recursiva}begin

    if n=4 then exit;

    writeln(c[n],' ',c[j], ' ',c[k]);writeln(c[n],' ',c[k], ' ',c[j]);

    j:=k;

    k:=n;

    mostra(n+1);end;

    begin

    clrscr;

    readln(x); c[1]:=x;

    readln(x); c[2]:=x;

    readln(x); [3]:=x;Writeln;

    j:=2;

    k:=3;

    mostra(1); {chama recursiva}end.

    Na forma iterativa:

    AlgoritmoDeclare x literal

    Declare c array[1..3] de literal

    Declare a, i, j, k numricoLeia x

    c[1]:=x

    Leia x

  • 7/24/2019 11 Recursividade Em Estrutura de Dados

    10/10

    Algoritmos Recursivos Professor Srgio Furgeri

    Pgina 10

    c[2]:=xLeia x

    c[3]:=x

    i:=1;j:=2;

    k:=3;a:=0;

    Repita enquanto a