Вы находитесь на странице: 1из 40

11/10/2014 Mg.

Edgar Ruiz Lizama


1
UNMSM FACULTAD DE INGENIERIA INDUSTRIAL
ALGORITMOS Y PROGRAMACION
RECURSIVIDAD
DEFINICIN: La recursividad, es un
concepto muy importante en
matemticas, pues muchas definiciones
se sustentan en la recursividad. Se dice
que un objeto es recursivo, cuando en
parte esta formado o definido en trminos
de s mismo.
11/10/2014 Mg. Edgar Ruiz Lizama
2
SON EJEMPLOS DE DEFINICIONES RECURSIVAS:

1. LAS ESTRUCTURAS DE RBOL EN COMPUTACION:
SEA T UN RBOL
a) t=0 es un rbol
denominado rbol
vaco.
b) Si t1 y t2son rboles,
entonces las
estructuras formadas
por un nodo con dos
rboles
descendientes
tambin son un rbol.
11/10/2014 Mg. Edgar Ruiz Lizama
3
t
t1
t2
2. LOS NMEROS NATURALES
a) 0 (CERO) es un nmero natural
b) El sucesor de un nmero natural es otro
nmero natural.

c) 0,1,2,3,4,5,6, . . .
11/10/2014 Mg. Edgar Ruiz Lizama
4
3. EL FACTORIAL DE UN ENTERO NO
NEGATIVO
11/10/2014 Mg. Edgar Ruiz Lizama
5

0 ); 1 ( *
0 ; 1
) (
n si n Fact n
n si
n Fact
El clculo manual para el factorial de 5 se presenta a
continuacin y luego el programa que implementa la
definicin recursiva para el factorial.
CALCULO PARA EL FACTORIAL DE 5:
5!
5*4!
3*2!
4*3!
2*1!
1*0!
5!
2*1!
3*2!
4*3!
5*4!
1*0!
1 1 Caso base
1 es devuelto
1!=1*1=1 es devuelto
2!=2*1=2 es devuelto
3!=3*2=6 es devuelto
4!=4*6=24 es devuelto
5!=5*24=120 es devuelto
120 es el valor final devuelto
( 1 )
( 2 )
( 3 )
( 4 )
( 5 )
( 6 )
(a) Secuencia de llamadas recursivas (b) Valores devueltos en cada llamada
recursiva
11/10/2014 Mg. Edgar Ruiz Lizama
6
#include <iostream>
//funcion factorial recursivo
using namespace std;
float fact(int n);
int main() //recur1.cpp
{
int n;
cout<<"Ingrese n : ";
cin>>n;
cout<<"el factorial de "<<n<<" es: "<<fact(n)<<endl;

return 0;
}
float fact(int n)
{
if(n==0)
return 1;
else
return n*fact(n-1);
}
11/10/2014 Mg. Edgar Ruiz Lizama
7
3. LA SUCESIN DE FIBONACCI
11/10/2014 Mg. Edgar Ruiz Lizama
8
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55...........

1 ); 2 ( ) 1 (
1 o 0 ;
) (
n si n Fibo n Fibo
n n si n
n Fibo
El programa que implementa esta definicin recursiva
viene a continuacin.
CONJUNTO DE LLAMADAS RECURSIVAS A
LA FUNCIN FIBONACCI DE 4
fib(4)
fib(3) fib(2)
fib(0)
fib(1) fib(2)
fib(1)
return 1
return 1
return 0
return +
+
+
return
return
fib(0) fib(1)
return 1 return 0
+ return
11/10/2014 Mg. Edgar Ruiz Lizama
9

#include <iostream>
// funcion fibonacci recursiva
float fibo(int n);
using namespace std;
int main() //recur2.cpp
{
int n;
cout<<"Ingrese n : ";
cin>>n;
cout<<"El numero de Fibonacci es : "<<fibo(n)<<endl;

return 0;
}
float fibo(int n)
{
if(n==0 || n==1)
return n;
else
return fibo(n-1)+fibo(n-2);
}
11/10/2014 Mg. Edgar Ruiz Lizama
10
EJECUCION DEL PROGRAMA:
11/10/2014 Mg. Edgar Ruiz Lizama
11
TODA FUNCIN RECURSIVA TIENE 2 PARTES:
1. El caso Base: Es el caso trivial
2. El caso general: Es el que se
acerca al caso base.
11/10/2014 Mg. Edgar Ruiz Lizama
12
Sin duda la utilidad de la recursin radica en la
posibilidad de expresar un conjunto infinito de
objetos mediante una proposicin finita.
PASOS A SEGUIR PARA DESARROLAR
PROBLEMAS DE RECURSIVIDAD
1. Dividir el problema en dos partes.
2. Tener un caso base trivial.
3. Combinar la regla de paro usando if.
4. Verificar que la recursion pueda
terminar.
5. Dibujar un rbol de recursion.
11/10/2014 Mg. Edgar Ruiz Lizama
13
4. ALGORITMO RECURSIVO PARA LA
MULTIPLICACIN
11/10/2014 Mg. Edgar Ruiz Lizama
14

1 ); 1 , (
1 ;
) , (
b si b a Multip a
b si a
b a Multip
La prueba para multiplicar 6 x 4 y el programa
que implementa la definicin recursiva para la
multiplicacin de dos nmeros enteros viene a
continuacin.
DESARROLLO RECURSIVO PARA EL
PRODUCTO
Sea a=6 y b=4
prod(6,4)=6+prod(6,3)
prod(6,3)=6+prod(6,2)
prod(6,2)=6+prod(6,1)
prod(6,1)=6
prod(6,2)=6+6
prod(6,3)=6+12
=6+18
prod(6,4)=24 Rpta!.
11/10/2014 Mg. Edgar Ruiz Lizama
15
//multiplicacion a*b recursiva
#include <iostream>

int multrec(int a, int b);
using namespace std;
int main()
{
int a, b;
cout<<"Ingrese dos enteros ";
cin>>a>>b;
cout<<"\nEl producto es "<<multrec(a,b)<<endl;

return 0;
}

int multrec(int a, int b)
{
if (b == 1)
return a;
else
return (a + multrec(a,b-1));
}
11/10/2014 Mg. Edgar Ruiz Lizama
16
5. FUNCIN POTENCIA RECURSIVA X
N
11/10/2014 Mg. Edgar Ruiz Lizama
17


0 ); (
0 ; 1
1
n si X X
n si
X
n
n
La prueba manual para elevar 2 a la 4 y el
programa que implementa la definicin
recursiva para la potencia X a la n, viene a
continuacin.
DESARROLLO RECURSIVO PARA LA
POTENCIA
11/10/2014 Mg. Edgar Ruiz Lizama
18
potencia (2,4)=2*potencia(2,3)
potencia(2,3)=2*potencia(2,2)
potencia(2,2)=2*potencia(2,1)
potencia(2,0)=1
=2*2=>4
=2* 4
=2*8
potencia(2,4)=16
//funcion potencia x a la n
#include <iostream>

float potenrec(float x, int n);
using namespace std;
int main() //recur4.cpp
{
int x, n;
cout<<"Ingrese base y exponente enteros positivos ";
cin>>x>>n;

cout<<x<<" a la "<<n<<" = "<<potenrec(x,n)<<endl;
return 0;
}
float potenrec(float x, int n)
{
if (n==0)
return 1;
else
return (x*potenrec(x,n-1));
}
11/10/2014 Mg. Edgar Ruiz Lizama
19
6. SUMAR RECURSIVAMENTE LOS
ELEMENTOS DE UN ARRAY
11/10/2014 Mg. Edgar Ruiz Lizama
20
Suma con 1 elemento: suma(a,1) = a[0]
Suma con 2 elementos: suma(a,2) = a[0] + a[1] = a[1] + suma(a,1)
Suma con 3 elementos: suma(a,3) = a[0]+a[1]+a[2] = a[2] +
suma(a,2)
. . .
Suma con n elementos:
Suma(a,n) = a[0]+a[1]+a[2]+a[3]+...+a[n-1] = a[n-1] + suma(a,n-1)
1 3 5 7 15 21
a[0] a[1] a[2] a[3] a[n-2] a[n-1]
. . .
LA RELACIN DE RECURRENCIA PARA LA SUMA
RECURSIVA DE UN ARRAY ES:

1 ); 1 , ( ] 1 [
1 ]; 0 [
) , (
n si n a Sumarec n a
n si a
n a Sumarec
11/10/2014 Mg. Edgar Ruiz Lizama
21
El programa que implementa la definicin recursiva
para la suma de los n, elementos de un array viene a
continuacin.
//sumar recursivamente los elementos de un array
#include <iostream>

int sumarec(int a[], int n);
using namespace std;
int main()
{
int a[] = {1,2,3,4,5};
int n = 5;

cout<<"Suma de elementos = "<<sumarec(a,n)<<endl;

return 0;
}
int sumarec(int a[], int n)
{
if (n == 1)
return a[0];
else
return (a[n-1] + sumarec(a,n-1));
}
11/10/2014 Mg. Edgar Ruiz Lizama
22
7. ENCONTRAR EL MXIMO VALOR DE UN
ARREGLO POR RECURSIVIDAD
Mximo con 1 elemento: Mximo(a,1) = a[0]
Mximo con 2 elementos: Mximo(a,2) = Mximo(a[1], Mximo(a,1))
Mximo con 3 elementos: Mximo(a,3) = Mximo(a[2], Mximo(a,2))
. . .
Mximo con n elementos:
Mximo(a,n) = Mximo(a[n-1], Mximo(a,n-1))
11/10/2014 Mg. Edgar Ruiz Lizama
23
7 3 5 95 15 25
a[0] a[1] a[2] a[3] a[n-2] a[n-1]
. . .
El programa que implementa la funcin recursiva para
hallar el mximo valor en una array de n, elementos es
//encuentra recursivamente el maximo elemento de un array
#include <iostream>
const int MAX=20;
int max(int n,int x[]);
using namespace std;
int main() //recur8.cpp E. Raffo Lecca
{
int x[MAX], n;
cout<<"Cuantos elementos en el array? ";
cin>>n;
for (int i=0; i<n; i++)
cin>>x[i];
cout<<"El maximo elemento es: "<<max(n,x)<<endl;
return 0;
}
int max(int n,int x[])
{
if(n==1)
return x[0];
if(x[n-1]>max(n-1,x))
return x[n-1];
else
return max(n-1,x);
}
11/10/2014 Mg. Edgar Ruiz Lizama
24
8. INVERTIR UNA CADENA DE CARACTERES EN
FORMA RECURSIVA
//imprime una cadena en reversa
#include <iostream>
#include <stdio.h>
const int MAX = 80;

void reversa_frase(int n);
using namespace std;
int main() //reverfra.cpp E. Raffo Lecca
{
int n=8; // Hola C++
cout<<"Ingrese caracter a caracter con un ENTER cada vez: ";
reversa_frase(n); cout<<endl;
return 0;
}
11/10/2014 Mg. Edgar Ruiz Lizama
25
CONTINUACIN...

void reversa_frase(int n)
{
char s[MAX];
if (n>1)
{ gets(s);
reversa_frase(n-1);
}
else
gets(s);
puts(s);
}
11/10/2014 Mg. Edgar Ruiz Lizama
26
EJECUCIN DEL PROGRAMA
11/10/2014 Mg. Edgar Ruiz Lizama
27
9. CONTAR LA OCURRENCIA DE UN CARCTER
EN UNA CADENA
/*cuenta recursivamente la ocurrencia de un caracter en una
cadena */
#include <iostream>
#include <stdio.h> // para getchar()
int contador(char ch, char s[]);
using namespace std;

int main() //recur6.cpp
{ char ch, s[80];
cout<<"ingrese cadena : ";
cin.getline(s,80);
cout<<"ingrese caracter a contar : ";
ch=getchar();
cout<<"cantidad de ocurrencias del caracter "<<ch<<" = "
<<contador(ch,s)<<endl;
cout<<endl;
return 0;
}
11/10/2014 Mg. Edgar Ruiz Lizama
28
CONTINUACIN...
int contador(char ch, char s[])
{
if (s[0]=='\0')
return 0; //caso base
else
if (ch==s[0]) //posicion actual
return 1+contador(ch,&s[1]); //incrementar en 1
else
return contador(ch,&s[1]);
}
11/10/2014 Mg. Edgar Ruiz Lizama
29
EJECUCIN DEL PROGRAMA
11/10/2014 Mg. Edgar Ruiz Lizama
30
10. BSQUEDA BINARIA RECURSIVA
#include <iostream>
//binsearch : busqueda binaria recursiva

int binsearch(int a[],int x,int der, int izq);
using namespace std;
int main() //recur7.cpp E. Raffo Lecca
{
int der=0,izq=6,x=5;
int a[]={1,2,3,4,5,6,7};
cout<<x<<" esta en la posicion "<<binsearch
(a,x,der,izq) << endl;
cout<<endl;
return 0;
}
11/10/2014 Mg. Edgar Ruiz Lizama
31
CONTINUACIN...

int binsearch(int a[],int x,int der,int izq)
{
int mitad;
if(der>izq)
return -1;
mitad=(der+izq)/2;
return (x==a[mitad]?mitad:x<a[mitad]?
binsearch(a,x,der,mitad-1):
binsearch(a,x,mitad+1,izq));
}
11/10/2014 Mg. Edgar Ruiz Lizama
32
11. CASO DE UNA INVERSIN Y EL CLCULO
RECURSIVO PARA EL CAPITAL Y SU INTERS
Supngase que se deposita un monto m para lo cual se
recibe i % de inters anual. Se pide determinar mediante
la recursividad el capital que se tendr al cabo de n aos.

Solucin:
Asuma que m = 4000 y un inters i = 10%

Co = 4000 //capital inicial
C1 = Co + Co*10% //capital al finalizar el 1 ao
C2 = C1 + C1*10% //capital al finalizar el 2 ao
C2 = C2 + C2*10% //capital al finalizar el 3 ao
11/10/2014 Mg. Edgar Ruiz Lizama
33
(Tomado de la referencia nmero 1)
EN GENERAL:
CN=1.10*CN-1
OBTENIDO APARTIR CN=CN-1+CN-1*10%
De lo anterior puede ahora plantearse la siguiente
relacin recursiva
11/10/2014 Mg. Edgar Ruiz Lizama
34

0 si ); 1 ( * ) 1 (
0 si ;
) (
n n Capitalrec i
n m
n Capitalrec
ALGORITMO
capitalRec(n,m,i)
if n = 0 then
capitalRec = m
else
capitalRec = (1+i)*capitalRec(n-1,m,i)
end
11/10/2014 Mg. Edgar Ruiz Lizama
35
SEA N= 4. LA TABLA SIGUIENTE MUESTRA LOS CLCULOS
QUE SE VAN SUCEDIENDO EN LAS VARIABLES Y LOS
VALORES ALMACENADOS EN LA PILA
Paso n Pila CapitalRec
0 4
1 4 1.10
2 3 1.10,1.10
3 2 1.10,1.10,1.10
4 1 1.10,1.10,1.10,1.10
5 0 1.10,1.10,1.10,1.10 4000
6 1 1.10,1.10,1.10 4400=4000*1.10
7 2 1.10,1.10 4840=(4400)*1.10
8 3 1.10 5324=4840*1.10
9 4 5856=5324*1.10
11/10/2014 Mg. Edgar Ruiz Lizama
36
11/10/2014 Mg. Edgar Ruiz Lizama
37
Capital Rec.(4)
1.10*Capital Rec.(3)
1.10*Capital Rec.(2)
1.10*Capital Rec.(1)
1.10*Capital Rec.(0)
4000
5856.4 (Valor final devuelto)
Capital Rec.(4)
1.10*5324=5856.4 es devuelto
1.10*Capital Rec.(3)
1.10*4840=5324 es devuelto
1.10*Capital Rec.(2)
1.10*4400=4840 es devuelto
1.10*Capital Rec.(1)
1.10*4000=4400 es devuelto
1.10*Capital Rec.(0)
4000 es devuelto
4000
(a) Secuencia de llamadas
recursivas
(b) Valores
devueltos en cada
llamada recursiva
CDIGO DEL PROGRAMA
#include <iostream>
#include <stdlib.h>
// capital recursivo
float CapitalRec(int n,float m, float x);
using namespace std;
int main() //capitrec.cpp
{
int n;
float m, i;
cout<<"Ingrese el capital: ";
cin>>m;
cout<<"\nIngrese el tiempo en aos: ";
cin>>n;
cout<<"\nIngrese porcentaje o interes anual: ";
cin>>i;
cout<<"\nEl capital al cabo de "<<n<<" aos es = $"<<
CapitalRec(n,m,i);
cout<<endl<<endl;
return 0;
}
11/10/2014 Mg. Edgar Ruiz Lizama
38
CONTINUACIN...

float CapitalRec(int n,float m,float i)
{
if (n==0)
return m;
else
return (1.0+i)*CapitalRec(n-1,m,i);
}
11/10/2014 Mg. Edgar Ruiz Lizama
39
REFERENCIAS
1. Cairo O. Y Guardati S. Estructura de datos 2da. Ed. Editorial
McGrawHill. Mxico 2002.
2. Deitel y Deitel, Como programar en C++ 4ta. ed. Editorial
Prentice Hall. Mxico, 2003.
3. Langsam; Augenstein; y Tenenbaum, Estructuras de Datos con
C++Editorial Prentice Hall, Mxico 1996.
4. Raffo Lecca E. Turbo C 3.0 Raffo Lecca Editores, Lima,1995.
5. Ruiz Lizama Edgar, Programacin con C++ 1ra. ed. Fondo
Editorial de la UNMSM., Lima Per, 2009
6. Ruiz Lizama Edgar, Curso de Lenguaje C 1ra. ed. Facultad de
Ingeniera Industrial UNMSM. Lima, 1999.
7. Savitch Walter, Resolucin de problemas con C++ 2da. Ed.
Editorial Pearson de Mxico, 2000.
8. Sedgewick Algoritmos en C++ 1ra. Ed. Addison Wesley
Iberoamericana U.S.A. 1995.

ERL/2013
11/10/2014 Mg. Edgar Ruiz Lizama
40

Вам также может понравиться