Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Tecnología de la Programación 2
Temario
Tema 1. Recursividad
Tecnología de la Programación 3
Tema 1. Recursividad
1.1 Definición de Recursividad
Se dice que un objeto es recursivo si forma parte de sí mismo o se
define en función de sí mismo.
Tecnología de la Programación 4
Tema 1. Recursividad
1.1 Definición de Recursividad
Ejemplos:
Números naturales:
1 es un número natural
El siguiente de un número natural es un número natural
3! = 3 · (3-1)!
= 3 · 2!
= 3 · 2 · (2-1)!
= 3 · 2 · 1!
= 3 · 2 · 1 · (1-1)!
= 3 · 2 · 1 · 0!
= 3 · 2 · 1 · 1
= 6
Tecnología de la Programación 5
Tema 1. Recursividad
1.1 Definición de Recursividad
Un algoritmo es recursivo si se invoca a sí mismo al menos una
vez.
Recursividad directa:
El algoritmo contiene una llamada explícita a sí mismo, es decir, A
invoca a A.
Recursividad indirecta:
El algoritmo se invoca a sí mismo de forma indirecta, es decir, A
invoca a B y B invoca a A.
Tecnología de la Programación 6
Tema 1. Recursividad
1.1 Definición de Recursividad
Un algoritmo recursivo está bien construido si:
Tecnología de la Programación 7
Tema 1. Recursividad
1.2 Recursividad en C++
Multiplicación n · m (m ≥ 0)
Caso Base: (m = 0) n · 0 = 0
Caso General: (m > 0) n · m = n + n · (m - 1)
// m>=0
int multiplica(int n, int m)
{
if (m==0) return 0;
return n+multiplica(n,m-1);
}
Tecnología de la Programación 8
Tema 1. Recursividad
1.2 Recursividad en C++
División entera n / m (n ≥ 0 y m>0)
// n>=0, m>0
int divide(int n, int m)
{
if (n<m) return 0;
return 1+divide(n-m,m);
}
Tecnología de la Programación 9
Tema 1. Recursividad
1.2 Recursividad en C++
Módulo n % m (n ≥ 0 y m > 0)
// n>=0, m>0
int modulo(int n, int m)
{
if (n<m) return n;
return modulo(n-m,m);
}
Tecnología de la Programación 10
Tema 1. Recursividad
1.2 Recursividad en C++
Potencia nm (m ≥ 0)
Caso Base: (m = 0) n 0 = 1
Caso General: (m > 0) n m = n · n m - 1
// m>=0
int potencia(int n, int m)
{
if (m==0) return 1;
return n*potencia(n,m-1);
}
Tecnología de la Programación 11
Tema 1. Recursividad
1.2 Recursividad en C++
Factorial n! (n ≥ 0)
Caso Base: (n = 0) 0! = 1
Caso General: (n > 0) n! = n · ( n – 1 )!
// n>=0
int factorial(int n)
{
if (n==0) return 1;
return n*factorial(n-1);
}
Tecnología de la Programación 12
Tema 1. Recursividad
1.2 Recursividad en C++
Fibonacci fib(n) (n ≥ 0)
// n>=0
int fibonacci(int n)
{
if (n<=1) return n;
return fibonacci(n-2)+fibonacci(n-1);
}
Tecnología de la Programación 13
Tema 1. Recursividad
1.2 Recursividad en C++
Hanoi h(n,a,b,c) (n ≥ 1)
// n>=1
void hanoi(int n, char a, char b, char c)
{
if (n>1) hanoi(n-1,a,c,b);
cout << “Mover de “ << a << “ a “ << c << endl;
if (n>1) hanoi(n-1,b,a,c);
}
Tecnología de la Programación 14
Tema 1. Recursividad
1.2 Recursividad en C++
Nota C++: Entrada / Salida
#include <iostream>
using namespace std;
Tecnología de la Programación 15
Tema 1. Recursividad
1.2 Recursividad en C++
Nota C++: Entrada / Salida
#include <iostream>
using namespace std;
Tecnología de la Programación 16
Tema 1. Recursividad
Ejercicios Propuestos
Máximo Común Divisor mcd(n,m) (n ≥ 0, m ≥ 0, n ≥m)
Tecnología de la Programación 17
Tema 1. Recursividad
1.3 Esquemas recursivos
Divide y Vencerás
Tecnología de la Programación 18
Tema 1. Recursividad
1.3 Esquemas recursivos
Divide y Vencerás: Búsqueda Binaria
Busca un elemento e en un vector v ordenado.
Devuelve el índice de una ocurrencia del elemento e en del vector v.
Si el vector v no contiene ninguna ocurrencia del elemento e, devuelve -1.
// v está ordenado
int buscabin(int v[], int ini, int fin, int e)
{
if (ini>fin) return -1;
int med = (ini+fin)/2;
if (v[med]==e) return med;
if (v[med]>e) return buscabin(v,ini,med-1,e);
if (v[med]<e) return buscabin(v,med+1,fin,e);
}
// v está ordenado, tam es el numero de elementos de v
int buscabin(int v[], int e)
{
return buscabin(v,0,sizeof(v),e);
}
Tecnología de la Programación 19
Tema 1. Recursividad
1.3 Esquemas recursivos
Divide y Vencerás: Ordenación por Mezcla
Ordena un vector v desde el índice ini hasta el índice fin.
Tecnología de la Programación 20
Tema 1. Recursividad
1.3 Esquemas recursivos
Vuelta Atrás: Una solución
Devuelve cierto si encuentra una solución a partir de un paso, y falso en caso
contrario. Si encuentra una solución la devuelve en el parámetro solucion.
Tecnología de la Programación 21
Tema 1. Recursividad
1.3 Esquemas recursivos
Nota C++: Paso de objetos
Paso por valor: Ineficiente
void funcion(solucion s)
Tecnología de la Programación 22
Tema 1. Recursividad
1.3 Esquemas recursivos
Vuelta Atrás: Una solución
Solución compuesta por n pasos y m posibilidades para cada paso.
El parámetro solucion debe pasarse por referencia porque es de salida.
bool VA(int i, solucion & s)
{
if (i==n) return true;
for(int j=0;j<m;j++)
if (aceptable(s,i,j))
{
anotar(s,i,j);
if (VA(i+1,s)) return true;
cancelar(s,i,j);
}
return false;
}
Tecnología de la Programación 23
Tema 1. Recursividad
1.3 Esquemas recursivos
Vuelta Atrás: Todas las soluciones
Obtiene todas las soluciones posibles a partir de un paso.
Tecnología de la Programación 24
Tema 1. Recursividad
1.3 Esquemas recursivos
Vuelta Atrás: Todas las soluciones
Solución compuesta por n pasos y m posibilidades para cada paso.
void VA(int i, solucion & s)
{
if (i==n) imprime(s);
else
for(int j=0;j<m;j++)
if (aceptable(s,i,j))
{
anotar(s,i,j);
VA(i+1,s);
cancelar(s,i,j);
}
}
Tecnología de la Programación 25
Tema 1. Recursividad
1.3 Esquemas recursivos
Vuelta Atrás: Ocho Reinas
n = 8 (8 pasos, un paso por cada reina)
m = 8 (8 posibilidades para cada reina)
Tecnología de la Programación 26
Tema 1. Recursividad
1.3 Esquemas recursivos
Vuelta Atrás: Ocho Reinas
void inicia(solucion & s)
{
for(int j=0;j<8;j++) s.a[j] = true;
for(int j=0;j<15;j++) { s.b[j] = true; s.c[j] = true; }
}
void imprime(const solucion & s)
{
for(int j=0;j<8;j++) cout << s.x[j] << " "; cout << endl;
}
bool aceptable(const solucion & s, int i, int j)
{
return s.a[j]&&s.b[i+j]&&s.c[i-j+7];
}
void anotar(solucion & s, int i, int j)
{
s.x[i]=j; s.a[j]=false; s.b[i+j]=false; s.c[i-j+7]=false;
}
void cancelar(solucion & s, int i, int j)
{
s.a[j]=true; s.b[i+j]=true; s.c[i-j+7]=true;
}
Tecnología de la Programación 27
Tema 1. Recursividad
1.4 Tiempo de ejecución de los algoritmos recursivos
Expansión de recurrencias
Tecnología de la Programación 28
Tema 1. Recursividad
1.4 Tiempo de ejecución de los algoritmos recursivos
Ejemplo: Factorial
Ecuación de recurrencia:
T(0) = c1
T(n) = T(n-1) + c2 si n>0
Expansión de recurrencias:
T(n) = T(n-1)+c2 = [T(n-2)+c2]+c2 = T(n-2)+2c2 = [T(n-3)+c2]+2c2 = T(n-3)+3c2
Tecnología de la Programación 29
Tema 1. Recursividad
1.4 Tiempo de ejecución de los algoritmos recursivos
Ecuación de recurrencia:
T(1) = c1
T(n) = T(n/2) + c2 si n>1
Expansión de recurrencias:
T(n) = T(n/2)+c2 = [T(n/4)+c2]+c2 = T(n/4)+2c2 = [T(n/8)+c2]+2c2 = T(n/8)+3c2
Tecnología de la Programación 30
Tema 1. Recursividad
1.4 Tiempo de ejecución de los algoritmos recursivos
Ejemplo: Mergesort
Ecuación de recurrencia:
T(1) = c1
T(n) = 2 T(n/2) + n c2 si n>1
Expansión de recurrencias:
T(n) = 2T(n/2)+nc2 = 2[2T(n/4)+(n/2)c2]+nc2 = 4T(n/4)+2nc2 = 8T(n/8)+3nc2
Tecnología de la Programación 31
Tema 1. Recursividad
1.5 Recursión vs Iteración
La recursión implica múltiples llamadas y el uso de la pila interna para
almacenar, en cada llamada recursiva, los parámetros de llamada,
variables locales y dirección de retorno, lo que hace que en general
sea más ineficiente que el diseño iterativo.
Tecnología de la Programación 32
Tema 1. Recursividad
1.5 Recursión vs Iteración
Multiplicación n · m (m ≥ 0)
Caso Base: (m = 0) n · 0 = 0
Caso General: (m > 0) n · m = n + n · (m - 1)
Tecnología de la Programación 33
Tema 1. Recursividad
1.5 Recursión vs Iteración
División entera n / m (n ≥ 0 y m > 0)
Tecnología de la Programación 34
Tema 1. Recursividad
1.5 Recursión vs Iteración
Módulo n % m (n ≥ 0 y m > 0)
Tecnología de la Programación 35
Tema 1. Recursividad
1.5 Recursión vs Iteración
Potencia nm (m ≥ 0)
Caso Base: (m = 0) n 0 = 1
Caso General: (m > 0) n m = n · n m - 1
Tecnología de la Programación 36
Tema 1. Recursividad
1.5 Recursión vs Iteración
Factorial n! (n ≥ 0)
Caso Base: (n = 0) 0! = 1
Caso General: (n > 0) n! = n · ( n – 1 )!
Tecnología de la Programación 37
Tema 1. Recursividad
1.5 Recursión vs Iteración
Fibonacci fib(n) (n ≥ 0)
Caso Base: (n ≤ 1) fib(n) = n
Caso General: (n > 1) fib(n) = fib(n-2) + fib(n-1)
// n>=0 (versión recursiva)
int fibonacci(int n)
{
if ((n<=1)) return n;
return fibonacci(n-2)+fibonacci(n-1);
}
// n>=0 (version iterativa)
int fibonacci(int n)
{
if (n<=1) return n;
int aux[n+1];
aux[0] = 0;
aux[1] = 1;
for(int i=2; i<=n; i++) aux[i] = aux[i-2] + aux[i-1];
int res = aux[n];
free(aux);
return res;
}
Tecnología de la Programación 38
Tema 1. Recursividad
1.5 Recursión vs Iteración
Búsqueda Binaria
// v está ordenado (versión recursiva)
int buscabin(int v[], int ini, int fin, int e)
{
if (ini>fin) return -1;
int med = (ini+fin)/2;
if (v[med]==e) return med;
if (v[med]>e) return buscabin(v,ini,med-1,e);
if (v[med]<e) return buscabin(v,med+1,fin,e);
}
// v está ordenado (versión iterativa)
int buscabin(int v[], int ini, int fin, int e)
{
while(ini<=fin)
{
int med = (ini+fin)/2;
if (v[med]==e) return med;
if (v[med]>e) fin = med-1; else ini = med+1;
}
return -1;
}
Tecnología de la Programación 39
Tema 1. Recursividad
Ejercicios Propuestos
Máximo Común Divisor mcd(n,m) (n ≥ 0, m ≥ 0, n ≥m)
Tecnología de la Programación 40
Tema 1. Recursividad