Está en la página 1de 40

ESTRUCTURA DE DATOS:

Tema 3. Recursividad

Presenta: David Martínez Torres


Universidad Tecnológica de la Mixteca
Instituto de Computación
Oficina No. 37
dtorres@mixteco.utm.mx
Contenido

1. Directa e indirecta
2. Comparación entre funciones iterativas y recursivas
3. Funciones recursivas con arreglos
4. Ejemplo de transformación de un algoritmo recursivo a
iterativo
5. Ejemplo de transformación de un algoritmo iterativo a
recursivo
6. Conclusiones
7. Referencias

2
Definición

 Una función recursiva es una función que se


llama a sí misma, ya sea directa o indirecta a
través de otra función.

 Componentes
 Caso base. Es el resultado más simple, lo que
conoce la función.

 Paso de recursión. Problema poco menos


complejo que el original. También puede incluir la
palabra reservada return.

3
1. Recursión directa e indirecta

 Según el modo en que se realiza la llamada

 Directa: Cuando un método/función se invoca así


mismo. Ej., factorial, potencia, etc.

 Indirecta: Cuando un método/función puede


invocar a una segunda función/método que a su
vez invoca a la primera

4
1. Recursión directa

 Ejemplo 1 de recursión directa

5
1. Recursión directa

6
1. Recursión directa

int factorial(int n) //definición de la función


{
int fact;
if(n==0||n==1) //caso base
fact=1;
else
fact=n*factorial(n-1);
return fact;
} 7
1. Recursión directa

 Ejemplo 2 de recursión directa

8
1. Recursión directa

 Ejemplo: Imprimir contenido de una cola dinámica


 Caso base: si temp == NULL
printf(“NULL\n”);
 Paso de recursión: sino
printf(“%d ”,temp->dato);
imprimir(temp->sig)

cola
3 2 8
ini fin

temp 9
1. Recursión directa

int main(){

imprimir(cola.ini);

}
void imprimir(tipoNodoPtr temp){
if(temp==NULL)
printf(NULL);
else {
printf(%d ->,temp->dato);
imprimir(temp->sig);
}
} 10
1. Recursión directa

 La serie Fibonacci
0,1,1,2,3,5,8,13,21,34, …
 Empieza con 0 y 1, y tiene la propiedad que cada

número Fibonacci subsecuente es la suma de los


dos números Fibonacci previos.
 La serie Fibonacci se puede defininir
recursivamente de la siguiente manera:
fibonacci(0)=0
fibonacci(1)=1
fibonacci(n)=fibonacci(n-1)+fibonacci(n-2)
11
1. Recursión directa

12
1. Recursión directa

Torres de Hanoi
Definición del problema:

13
Torres de Hanoi /3
 Paso 0 – Inicial

 Configuración inicial:
 La torre A contiene n discos
de diferentes tamaños.
 En el tope sólo pueden ir los

discos más pequeños


 Objetivo:
 Mover todos los discos de la torre A a la torre B
 Mover:
 Toma el disco del tope de la torre y muévelo a otra
torre.
 Solo se puede mover un disco cada vez
 Después de un movimiento todos los discos han de
estar en alguna torre. 14
Torres de Hanoi /4

Paso 1. Recursión 1 Paso 2. Recursión 1

Mueve el disco tope de la torre A a la


torre C

Paso 3. Recursión 1 Paso 4. Recursión 1

15
Torres de Hanoi /5

Paso 5. Recursión 1 Paso 6. Recursión 1

Paso 7. Recursión 1 Paso 8. Mover

16
Torres de Hanoi /6

Paso 9. Recursión 2 Paso 10. Recursión 2

Paso 11. Recursión 2 Paso 12. Recursión 2

17
Torres de Hanoi /7

Paso 13. Recursión 2 Paso 14. Recursión 2

Paso 15. Recursión 2

18
Ideas para una solución recursiva

19
void moverTorres( int n, char desde, char hacia,char
temp){
if( n== 1 )
printf("Mueve de %c a %c .\n",desde,hacia);
else {
moverTorres( n- 1, desde, temp, hacia);
printf("Mueve de %c a %c .\n",desde,hacia);
moverTorres( n- 1, temp, hacia, desde);
}
}

20
1. Recursión indirecta

void A(char c){


int main(){
if(c>'A')
system("cls");
B(c);
A('D');
putchar(c);
printf("\n");
}
system("pause");
return 0;
void B(char c){
}
A(--c);
}

21
2. Comparación entre funciones recursivas e
iterativas
 Se basan en una estructura de control:
 las iterativas utilizan una estructura de repetición;
las recursivas una estructura de selección.
 Incluyen un ciclo de repetición:
 la iteración utiliza una estructura de repetición
explícita; la recursión lo hace mediante llamadas
de función repetidas.
 Incluyen una prueba de terminación:
 la iteración termina cuando falla la condición de
continuación del ciclo; la recursión termina cuando
se reconoce el caso base.
22
2. Comparación entre funciones recursivas e
iterativas

 Rendimiento
 En el caso de la recursión el invocar repetidamente la
misma función, puede resultar costosa en tiempo de
procesador y espacio de memoria.

 Por el contrario la iteración se produce dentro de una


función.

23
2. Comparación entre funciones recursivas e
iterativas

 ¿Cuándo elegir recursión?


 La razón fundamental es que existen numerosos
problemas complejos que poseen naturaleza
recursiva, por lo cual son más fáciles de
implementar con este tipo de algoritmos
 Sin embargo, en condiciones críticas de tiempo y
de memoria, la solución a elegir debe ser
normalmente de forma iterativa.

24
3. Funciones recursivas con arreglos de
estructuras

 Considere que tiene un arreglo de estructuras


con datos de alumnos. Escriba las siguientes
funciones recursivas:
 Encuentre el alumno que tiene el mayor promedio
 La suma de las edades de los alumnos
 Busque un alumno en el grupo y devuelva su
posición en el arreglo

25
3. Funciones recursivas con arreglos

 Ejemplo. La suma de los elementos del arreglo


int suma(int *vector, int fin){
int result;
if(fin==0)
result=vector[0];
else
result=vector[fin]+suma(vector,fin-1);
return result;
}

26
5. Transformación de un algoritmo recursivo
a iterativo

 Todo algoritmo recursivo puede ser transformado


en otro de tipo iterativo, pero para ello a veces
se necesita utilizar pilas donde almacenar los
cálculos parciales y el estado actual del
subprograma recursivo.

 Es posible estandarizar los pasos necesarios para


convertir un algoritmo recursivo en iterativo,
aunque el algoritmo así obtenido requerirá una
posterior labor de optimización.

27
5. Transformación de un algoritmo recursivo
a iterativo

 Tipos de transformaciones:

 Recursivas finales

 Recursivas no finales

28
Recursivas finales

Esquema recursivo Esquema iterativo

tipo f(tipo x){ tipo f(tipo x){


tipo res; tipo res;
while !(Condicion(x))
if(Condicion(x)) res = Pred(x);
res = (CasoBase)
else res = (CasoBase)
res = f(Pred(x)) return res;
return res; }
}
29
Recursivas finales: ejemplo

 Transformar el algoritmo recursivo, que calcula el


residuo de la división de dos enteros, a su
correspondiente algoritmo iterativo

30
Recursivas finales: ejemplo

Esquema recursivo Equivalencia


int residuo(int a, int b){
int res;
if(a<b) x → (a,b)
<Condicion (a,b)> → a<b
res=a;
<CasoBase> → a, si a<b
else Pred(a,b) → (a-b,b)
res=residuo((a-b),b);
return res;
}
31
Recursivas finales: ejemplo 1

Esquema recursivo Esquema iterativo


int residuo(int a, int b) int residuo(int a, int b)
{ {
int res; int res;
if(a<b) while(!(a<b))
res=a; a=a-b;
else return res=a;
res=residuo((a-b),b); }
return res;
} 32
Recursivas finales: ejemplo 2

Esquema recursivo Esquema iterativo


void imprimirL(tipoListaPtr void imprimirL(tipoListaPtr
lista) { lista) {
if(lista == NULL)
printf(“NULL”); while(!(lista == NULL)) {
else { printf(“%d ->”,
lista->dato);
printf(“%d ->”, lista=lista->sig);
lista->dato); }
imprimir(lista->sig); printf(“NULL”);
} }
}
33
Recursivas no finales

Esquema recursivo Esquema iterativo

tipo f(tipo x){ tipo f(tipo x){


tipo result; tipo result;
result= (CasoBase);
if (Condicion(x)) while !(Condicion(x)) {
result = (CasoBase); result= C(result,x);
else x= Pred(x);
result = }
C(x,f(Pred(x))); return result;
return result; }
} 34
Recursivas no finales: Ejemplo
 Transformar el algoritmo recursivo, que calcula la
suma de los elementos de un vector a su
correspondiente iterativo

35
Recursivas no finales: Ejemplo

Esquema recursivo  Equivalencias


 Recursiva
int suma (int *A, int i){ x →(A,i)
int result; <Condicion(A,i)> → i<0
if (i < 0) <CasoBase>para (A,-1) = 0
C(x,f(Pred(x)))=A[i]+Suma(A,i-1)
result= 0;
else
 Iterativa
result = A[i] + suma (A, i-1);
C(result,x)=result+A[i]
return result;
Pred(x)=i-1
}
 result es la pila donde se

almacenan las llamadas


36
Recursivas no finales: Ejemplo

Esquema recursivo Esquema iterativo

int suma (int *A, int i){ int suma (int *A, int i){
int result; int result;
if (i < 0) result=0;
result= 0; while (!(i <0)){
else result=result+A[i];
result = A[i] + suma (A, i-1); i=i-1;
return result; }
} return result;
}
37
Conclusiones /1

 Se basan en una estructura de control:


 la iteración utiliza una estructura de repetición; la
recursión una estructura de selección.
 Incluyen un ciclo de repetición:
 la iteración utiliza una estructura de repetición
explícita; la recursión lo hace mediante llamadas
de función repetidas.
 Incluyen una prueba de terminación:
 la iteración termina cuando falla la condición de
continuación del ciclo; la recursión termina cuando
se reconoce el caso base.
38
Conclusiones /2

 Tanto la iteración como la recursión pueden


ocurrir en forma infinita:
 En la iteración, si la prueba de continuación de
ciclo nunca se convierte en falsa
 En la recursión, si el paso de recursión no reduce
el problema de tal forma que converja con el caso
base
 La recursión invoca el mecanismo en forma
repetida y, por lo tanto, sobrecarga las llamadas
de función. Esto puede resultar costoso tanto en
tiempo de procesador como en espacio de
memoria.
39
7. Referencias
1. Joyanes Aguilar, Luis (1996) Fundamentos de programación,
Algoritmos y Estructura de datos. McGraw-Hill, México.
2. Deitel & Deitel (2001) C++ Como programar en C/C++.
Prentice Hall
3. Kerrighan y Ritchie “El lenguaje de programación”. Prentice
Hall
4. Gottfried, Byron (1999) “Programación en C” McGrawHill,
México.
5. Levine Gutierrez, Guillermo (1990) Introducción a la
computación y a la programación estructurada. McGraw-Hill,
México.
6. Levine Gutierrez, Guillermo (1990) Introducción a la
computación y a la programación estructurada. McGraw-Hill,
México.
7. H. Schildt, C++ from the Ground Up, McGraw-Hill, Berkeley,
CA, 1998
8. Keller,,AL;Pohl,Ira. A Book on C. 3 ª edición. Edit.Benjamin
umnings.1995

40

También podría gustarte