Tema 5 Recursividad
Tema 5 Recursividad
Tema 5 Recursividad
Recursividad en Pascal
En Pascal, a un procedimiento o función le es permitido no sólo invocar a otro procedimiento o función, sino
también invocarse a sí mismo. Una invocación de éste tipo se dice que es recursiva.
La función recursiva más utilizada como ejemplo es la que calcula el factorial de un número entero no
negativo, partiendo de las siguientes definiciones :
factorial (0) = 1
factorial (n) = n*factorial(n-1), para n>0
La función, escrita en Pascal, queda de la siguiente manera :
function factorial(numero:integer):integer;
begin
if numero = 0 then
factorial := 1
else
factorial := numero * factorial(numero-1)
end;
Si numero = 4, la función realiza los siguientes pasos :
1. factorial(4) := 4 * factorial(3) Se invoca a si misma y crea una segunda variable cuyo nombre es
numero y su valor es igual a 3.
2. factorial(3) := 3 * factorial(2) Se invoca a si misma y crea una tercera variable cuyo nombre es
numero y su valor es igual a 2.
3. factorial(2) := 2 * factorial(1) Se invoca a si misma y crea una cuarta variable cuyo nombre es
numero y su valor es igual a 1.
4. factorial(1) := 1 * factorial(0) Se invoca a si misma y crea una quinta variable cuyo nombre es
numero y su valor es igual a 0.
5. Como factorial(0) := 1, con éste valor se regresa a completar la invocación: factorial(1) := 1 * 1 , por
lo que factorial(1) := 1
6. Con factorial(1) := 1, se regresa a completar: factorial(2) := 2 * 1, por lo que factorial(2) := 2
7. Con factorial(2) := 2, se regresa a completar : factorial(3) := 3 * 2, por lo que factorial(3) := 6
8. Con factorial(3) := 6, se regresa a completar : factorial(4) := 4 * 6, por lo que factorial(4) := 24 y éste
será el valor que la función factorial devolverá al módulo que la haya invocado con un valor de
parámetro local igual a 4 .
Un ejemplo de procedimiento recursivo es el
siguiente:
Supóngase que una persona se mete a una piscina cuya profundidad es de 5 metros. Su intención es
tocar el fondo de la piscina y después salir a la superficie. Tanto en el descenso como en el
ascenso se le va indicando la distancia desde la superficie (a cada metro).
5. Recursividad Lenguaje C
La recursividad es la posibilidad de que una función se llame a sí misma, bien directa o
indirectamente. Un ejemplo típico es el cálculo del factorial de un número, definido en la forma:
N! = N * (N-1)! = N * (N-1) (N-2)! = N * (N-1)*(N-2)*...*2*1
Según lo visto hasta ahora, la reserva o asignación de memoria para vectores y matrices se hace
de forma automática con la declaración de dichas variables, asignando suficiente memoria para
resolver el problema de tamaño máximo, dejando el resto sin usar para problemas más pequeños.
Así, si en una función encargada de realizar un producto de matrices, éstas se dimensionan para un
tamaño máximo (100, 100), con dicha función se podrá calcular cualquier producto de un tamaño
igual o inferior, pero aun en el caso de que el producto sea por ejemplo de tamaño (3, 3), la
memoria reservada corresponderá al tamaño máximo (100, 100). Es muy útil el poder reservar más
o menos memoria en tiempo de ejecución, según el tamaño del caso concreto que se vaya a
resolver. A esto se llama reserva o gestión dinámica de memoria.
Existen en C dos funciones que reservan la cantidad de memoria deseada en tiempo de
ejecución. Dichas funciones devuelven –es decir, tienen como valor de retorno– un puntero a la
primera posición de la zona de memoria reservada. Estas funciones se llaman malloc() y calloc(), y
sus declaraciones, que están en la librería stdlib.h, son como sigue:
void *malloc(int n_bytes)
void *calloc(int n_datos, int tamaño_dato)
7
Una pila es un tipo especial de estructura de datos que se estudiará en INFORM ÁTICA 2.
Con gestión dinámica de memoria es más fácil utilizar matrices definidas como vectores de
punteros que matrices auténticas (también éstas podrían utilizarse con memoria dinámica: bastaría
reservar memoria para las N filas a la vez y asignar convenientemente los valores al vector de
punteros a[i]). El ejemplo anterior quedaría del siguiente modo:
// declaraciones
double **a, *x, *y;
void prod(int , double **, double *, double *);
...
// reserva de memoria para el vector de punteros a[]
a = calloc(N, sizeof(double *));
// reserva de memoria para toda la matriz a[][]
a[0] = calloc(N*N, sizeof(double));
// asignación de valor para los elementos del vector de punteros a[]
for (i=1; i<N; i++)
a[i] = a[i-1]+N;
// el resto del programa sería idéntico
...
LAS LIBRERÍAS DEL LENGUAJE C
A continuación se incluyen en forma de tabla algunas de las funciones de librería más utilizadas en el
lenguaje C.