new fundamentos programación 2013 10 - academia cartagena99 · 2014. 7. 13. · la pila del...

35
23/05/2014 1 10 Grado en Ingeniería Informática Grado en Ingeniería del Software Grado en Ingeniería de Computadores Luis Hernández Yáñez Facultad de Informática Universidad Complutense Fundamentos de la programación 20132014 Luis Hernández Yáñez Página 1 Fundamentos de la programación: Introducción a la recursión Concepto de recursión 2 Algoritmos recursivos Funciones recursivas 5 Diseño de funciones recursivas 8 Modelo de ejecución 9 La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial() 24 Tipos de recursión Recursión simple 38 recursión múltiple 39 Recursión anidada 41 Recursión cruzada 45 Código del subprograma recursivo 46 Parámetros y recursión 51 Ejemplos de algoritmos recursivos Búsqueda binaria 54 Torres de Hanoi 57 Recursión frente a iteración 62 Estructuras de datos recursivas 64

Upload: others

Post on 11-Oct-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

1

10

GradoenIngenieríaInformáticaGradoenIngenieríadelSoftware

GradoenIngenieríadeComputadores

LuisHernándezYáñez

FacultaddeInformáticaUniversidadComplutense

Fundamentos de la programación  2013‐2014

Luis Hernández Yáñez

Página 1Fundamentos de la programación: Introducción a la recursión

Concepto de recursión 2Algoritmos recursivos

Funciones recursivas 5Diseño de funciones recursivas 8

Modelo de ejecución 9La pila del sistema 10La pila y las llamadas a función 11Ejecución de la función factorial() 24

Tipos de recursiónRecursión simple 38recursión múltiple 39Recursión anidada 41Recursión cruzada 45

Código del subprograma recursivo 46Parámetros y recursión 51Ejemplos de algoritmos recursivos

Búsqueda binaria 54Torres de Hanoi 57

Recursión frente a iteración 62Estructuras de datos recursivas 64

Page 2: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

2

Luis Hernández Yáñez

Página 2Fundamentos de la programación: Introducción a la recursión

Luis Hernández Yáñez

Página 3Fundamentos de la programación: Introducción a la recursión

Recursión(recursividad,recurrencia)Sedicequealgosedefinedeformarecursivacuandoenladefiniciónapareceloqueseestádefiniendo.

Factorial(N)=Nx Factorial(N‐1) (N>0)

(wikipedia.org)(wikipedia.org)

Laimagendelpaqueteaparecedentrodelpropiopaquete,queasuvezcontieneotraimagendelpaquete...¡hastaelinfinito!

Laimagendelpaqueteaparecedentrodelpropiopaquete,queasuvezcontieneotraimagendelpaquete...¡hastaelinfinito!

(wikipedia.org)(wikipedia.org)

Cadatriánguloestáformadoporotros

triángulosmáspequeños.

Cadatriánguloestáformadoporotros

triángulosmáspequeños.

(http://farm1.static.flickr.com/83/229219543_edf740535b.jpg)

(http://farm1.static.flickr.com/83/229219543_edf740535b.jpg)

Lasmatrioskas rusasLasmatrioskas rusas

Page 3: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

3

Luis Hernández Yáñez

Página 4Fundamentos de la programación: Introducción a la recursión

RecursiónFactorial(N)=Nx Factorial(N‐1)

Elfactorialsedefineenfuncióndesímismo.

Losprogramasnopuedenmanejarlarecursióninfinita,quegeneraríaunbucleinfinitoenelprograma.

Ladefiniciónrecursivahadeiracompañadadeunoomáscasosbase.

Uncasobase esaquelenelquenoseutilizaladefiniciónrecursiva,sinoqueseproporcionaunpuntofinaldecálculo:

Cadavezqueseaplicaelcasorecursivo,elvalordeNsevaaproximandoalvalordelcasobase(0).

Nx Factorial(N‐1) siN>0 Casorecursivo(inducción)Factorial(N)=

1 siN=0 Casobase(odeparada)

Luis Hernández Yáñez

Página 5Fundamentos de la programación: Introducción a la recursión

Page 4: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

4

Luis Hernández Yáñez

Página 6Fundamentos de la programación: Introducción a la recursión

FuncionesrecursivasUnafunciónpuedeimplementarunalgoritmorecursivo:Lafunciónsellamaráasímismasinosehallegadoalcasobase.

long long int factorial(int n) {long long int resultado;if (n == 0) // Caso base

resultado = 1;else

resultado = n * factorial(n ‐ 1);

return resultado;}

Nx Factorial(N‐1) siN>0Factorial(N)=

1 siN=0

Luis Hernández Yáñez

Página 7Fundamentos de la programación: Introducción a la recursión

Funcionesrecursivaslong long int factorial(int n) {

long long int resultado;if (n == 0) // Caso base

resultado = 1;else

resultado = n * factorial(n ‐ 1);

return resultado;}

factorial(5) 5x factorial(4) 5x 4x factorial(3)

5x 4x 3x factorial(2) 5x 4x 3x 2x factorial(1)

5x 4x 3x 2x 1x factorial(0) 5x 4x 3x 2x 1x 1

120 CasobaseCasobase

factorial.cpp

Page 5: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

5

Luis Hernández Yáñez

Página 8Fundamentos de la programación: Introducción a la recursión

DiseñodefuncionesrecursivasUnafunciónrecursivadebesatisfacertrescondicionesparaestarbiendiseñada:

Caso(s)base:Debehaberalmenosuncasobasedeparada.

Inducción:Pasorecursivoqueprovocaunallamadarecursiva.Sepodrádemostrarqueescorrectoparadistintosparámetrosdeentrada.

Convergencia:Cadapasorecursivodebeacercarsealcasobase.

Describimoselproblemaentérminosdeproblemasmássencillos.

Lafunciónfactorial() tienecasobase(N=0),siendocorrectaparaNescorrectaparaN+1(inducción)yseacercacadavezmásalcasobase(N‐1estámáscercade0queN).

Nx Factorial(N‐1) siN>0Factorial(N)=

1 siN=0

Luis Hernández Yáñez

Página 9Fundamentos de la programación: Introducción a la recursión

Page 6: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

6

Luis Hernández Yáñez

Página 10Fundamentos de la programación: Introducción a la recursión

Modelodeejecuciónlong long int factorial(int n) {

long long int resultado;if (n == 0) // Caso base

resultado = 1;else

resultado = n * factorial(n ‐ 1);return resultado;

}

Cadallamadarecursivafuerzaunanuevaejecucióndelafunción,quedandointerrumpidalaactual.

Cadallamadaalafunciónutilizasuspropiosparámetrosporvaloryvariableslocales(n yresultado enestecaso).

Enlasllamadasalafunciónseutilizalapiladelsistemaparamantenerlosdatoslocalesyladireccióndevuelta.

Luis Hernández Yáñez

Página 11Fundamentos de la programación: Introducción a la recursión

Lapiladelsistema(stack)ElSOdisponeenlamemoriadelacomputadoravariasregionescondiferentespropósitos:

Pila (Stack)

Montón (Heap)

Datos del programa

Código del programa

S.O.

LlamadasafuncionesLlamadasafunciones

Memoriadinámica(Tema9)Memoriadinámica(Tema9)

MemoriaprincipalMemoriaprincipal

Page 7: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

7

Luis Hernández Yáñez

Página 12Fundamentos de la programación: Introducción a la recursión

Lapiladelsistema(stack)Lapilaseutilizaparaguardarencadallamadaafunciónlosdatoslocalesdelafunciónyladireccióndevuelta.

Esunaestructuradetipopila:listaLIFO(last‐infirst‐out)

Elúltimoqueentraeselprimeroquesale:

PilaPila

Entra4

Entra4

4

PilaPila

Entra7

Entra7

7

4

PilaPila

Entra2

Entra2

2

7

4

PilaPila

Sale2

Sale2

7

4

PilaPila

Luis Hernández Yáñez

Página 13Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezqueseproduceunallamadaaunafunciónsealojanenlapilasusdatoslocalesyladireccióndevuelta.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

PilaPila<DIR1><DIR1>

<DIR2><DIR2>

Llamadaafunción:SeguardaladireccióndevueltaLlamadaafunción:Seguardaladireccióndevuelta

Page 8: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

8

Luis Hernández Yáñez

Página 14Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezqueseproduceunallamadaaunafunciónsealojanenlapilasusdatoslocalesyladireccióndevuelta.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

<DIR1>

PilaPila<DIR1><DIR1>

<DIR2><DIR2>

Entradaenlafunción:SealojanlosdatoslocalesEntradaenlafunción:Sealojanlosdatoslocales

Luis Hernández Yáñez

Página 15Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezqueseproduceunallamadaaunafunciónsealojanenlapilasusdatoslocalesyladireccióndevuelta.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

b

a

<DIR1>

PilaPila<DIR1><DIR1>

<DIR2><DIR2> Llamadaafunción:SeguardaladireccióndevueltaLlamadaafunción:Seguardaladireccióndevuelta

Page 9: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

9

Luis Hernández Yáñez

Página 16Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezqueseproduceunallamadaaunafunciónsealojanenlapilasusdatoslocalesyladireccióndevuelta.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

<DIR2>

b

a

<DIR1>

PilaPila<DIR1><DIR1>

<DIR2><DIR2>

Entradaenlafunción:SealojanlosdatoslocalesEntradaenlafunción:Sealojanlosdatoslocales

Luis Hernández Yáñez

Página 17Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezquesevuelvedeunallamadaaunafunciónserecuperadelapilaladireccióndevueltadelafunciónanterior.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

x

<DIR2>

b

a

<DIR1>

PilaPila<DIR1><DIR1>

<DIR2><DIR2>

Vueltadelafunción:SeeliminanlosdatoslocalesVueltadelafunción:Seeliminanlosdatoslocales

Page 10: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

10

Luis Hernández Yáñez

Página 18Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezquesevuelvedeunallamadaaunafunciónserecuperadelapilaladireccióndevueltadelafunciónanterior.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

<DIR2>

b

a

<DIR1>

PilaPila<DIR1><DIR1>

<DIR2><DIR2>

Vueltadelafunción:SeobtieneladireccióndevueltaVueltadelafunción:Seobtieneladireccióndevuelta

Luis Hernández Yáñez

Página 19Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezquesevuelvedeunallamadaaunafunciónserecuperadelapilaladireccióndevueltadelafunciónanterior.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

b

a

<DIR1>

PilaPila<DIR1><DIR1>

<DIR2><DIR2>LaejecucióncontinúaenesadirecciónLaejecucióncontinúaenesadirección

Page 11: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

11

Luis Hernández Yáñez

Página 20Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezquesevuelvedeunallamadaaunafunciónserecuperadelapilaladireccióndevueltadelafunciónanterior.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

b

a

<DIR1>

PilaPila<DIR1><DIR1>

<DIR2><DIR2>

Vueltadelafunción:SeeliminanlosdatoslocalesVueltadelafunción:Seeliminanlosdatoslocales

Luis Hernández Yáñez

Página 21Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezquesevuelvedeunallamadaaunafunciónserecuperadelapilaladireccióndevueltadelafunciónanterior.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

<DIR1>

PilaPila<DIR1><DIR1>

<DIR2><DIR2>

Vueltadelafunción:SeobtieneladireccióndevueltaVueltadelafunción:Seobtieneladireccióndevuelta

Page 12: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

12

Luis Hernández Yáñez

Página 22Fundamentos de la programación: Introducción a la recursión

LapilaylasllamadasafunciónCadavezquesevuelvedeunallamadaaunafunciónserecuperadelapilaladireccióndevueltadelafunciónanterior.

...int funcB(int x) {

...return x;

}

int funcA(int a) {int b;...b = funcB(a);...   return b;

}

int main() {...cout << funcA(4);...

PilaPila<DIR1><DIR1>

<DIR2><DIR2>

LaejecucióncontinúaenesadirecciónLaejecucióncontinúaenesadirección

Luis Hernández Yáñez

Página 23Fundamentos de la programación: Introducción a la recursión

Mecanismodepilaadecuadoparallamadasafuncionesanidadas:

Lasllamadasterminanenelordencontrarioacomosellaman...int funcC(...) {...

}

int funcB(...) {...... funcC(...)

}

int funcA(...) {...... funcB(...)

}

int main() {...cout << funcA(...);...

funcC

funcB

funcA

PilaPila

LLAMADAS

LLAMADASV

UELTAS

VUELTAS

Page 13: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

13

Luis Hernández Yáñez

Página 24Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()long long int factorial(int n) {

long long int resultado;if (n == 0) // Caso base

resultado = 1;else

resultado = n * factorial(n ‐ 1);

return resultado;}

Cadavezqueserealizaunallamadarecursivaseguardanenlapilalosdatoslocales(n yresultado)yladireccióndevuelta.

Veamoscómoseejecutafactorial(5),obviandolasdireccionesdevuelta,quesondatosdebajonivelynoafectanalaexplicación.

Luis Hernández Yáñez

Página 25Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

resultado = ?

n = 5

PilaPila

Page 14: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

14

Luis Hernández Yáñez

Página 26Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

resultado = ?

n = 4

resultado = ?

n = 5

PilaPila

Luis Hernández Yáñez

Página 27Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

resultado = ?

n = 3

resultado = ?

n = 4

resultado = ?

n = 5

PilaPila

Page 15: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

15

Luis Hernández Yáñez

Página 28Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

factorial(2)

resultado = ?

n = 2

resultado = ?

n = 3

resultado = ?

n = 4

resultado = ?

n = 5

PilaPila

Luis Hernández Yáñez

Página 29Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

factorial(2)

factorial(1) resultado = ?

n = 1

resultado = ?

n = 2

resultado = ?

n = 3

resultado = ?

n = 4

resultado = ?

n = 5

PilaPila

Page 16: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

16

Luis Hernández Yáñez

Página 30Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

factorial(2)

factorial(1)

factorial(0)

resultado = 1

n = 0

resultado = ?

n = 1

resultado = ?

n = 2

resultado = ?

n = 3

resultado = ?

n = 4

resultado = ?

n = 5

PilaPila

Luis Hernández Yáñez

Página 31Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

factorial(2)

factorial(1)

factorial(0)

resultado = 1

n = 1

resultado = ?

n = 2

resultado = ?

n = 3

resultado = ?

n = 4

resultado = ?

n = 5

PilaPila

11

Page 17: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

17

Luis Hernández Yáñez

Página 32Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

factorial(2)

factorial(1)

factorial(0)resultado = 2

n = 2

resultado = ?

n = 3

resultado = ?

n = 4

resultado = ?

n = 5

PilaPila

11

11

Luis Hernández Yáñez

Página 33Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

factorial(2)

factorial(1)

factorial(0)

resultado = 6

n = 3

resultado = ?

n = 4

resultado = ?

n = 5

PilaPila

11

11

22

Page 18: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

18

Luis Hernández Yáñez

Página 34Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

factorial(2)

factorial(1)

factorial(0)

resultado = 24

n = 4

resultado = ?

n = 5

PilaPila

11

11

22

66

Luis Hernández Yáñez

Página 35Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

factorial(2)

factorial(1)

factorial(0)

resultado = 120

n = 5

PilaPila

11

11

22

66

2424

Page 19: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

19

Luis Hernández Yáñez

Página 36Fundamentos de la programación: Introducción a la recursión

Ejecucióndelafunciónfactorial()factorial(5)

factorial(4)

factorial(3)

factorial(2)

factorial(1)

factorial(0)

PilaPila

11

11

22

66

2424

120120

Luis Hernández Yáñez

Página 37Fundamentos de la programación: Introducción a la recursión

Page 20: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

20

Luis Hernández Yáñez

Página 38Fundamentos de la programación: Introducción a la recursión

RecursiónsimpleDecimosquelarecursiónessimplecuandoenlafunciónsólohayunallamadarecursiva.

Porejemplo,elcálculodelfactorialdeunnúmeroenteropositivo:

long long int factorial(int n) {long long int resultado;if (n == 0) // Caso base

resultado = 1;else

resultado = n * factorial(n ‐ 1);

return resultado;} UnallamadarecursivaUnallamadarecursiva

Luis Hernández Yáñez

Página 39Fundamentos de la programación: Introducción a la recursión

RecursiónmúltipleCuandoenlafunciónhayvariasllamadasrecursivasalapropiafunción,decimosquetenemosrecursiónmúltiple.

Porejemplo,elcálculodelosnúmerosdeFibonacci:

1 sin=1Fib(n)=

0 sin=0

Fib(n‐1)+Fib(n‐2) sin>1

DosllamadasrecursivasDosllamadasrecursivas

Page 21: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

21

Luis Hernández Yáñez

Página 40Fundamentos de la programación: Introducción a la recursión

Recursiónmúltiple:losnúmerosdeFibonacci...int fibonacci(int n) {

int resultado;if (n == 0)

resultado = 0;else if (n == 1)

resultado = 1;else

resultado = fibonacci(n ‐ 1) + fibonacci(n ‐ 2);

return resultado;}

int main() {for (int i = 0; i < 20; i++)

cout << fibonacci(i) << endl;

return 0;}

1 sin=1Fib(n)=

0 sin=0

Fib(n‐1)+Fib(n‐2) sin>1

fibonacci.cpp

Luis Hernández Yáñez

Página 41Fundamentos de la programación: Introducción a la recursión

RecursiónanidadaLarecursiónanidadalatenemoscuandoenunallamadarecursivaalgunodelosargumentosconsisteenotrallamadarecursiva.

Porejemplo,elcálculodelosnúmerosdeAckermann:

Ack(m‐1,1) sim>0yn=0Ack(m,n)=

n+1 sim=0

Ack(m‐1,Ack(m,n‐1)) sim>0yn>0

ArgumentoqueesunallamadarecursivaArgumentoqueesunallamadarecursiva

Page 22: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

22

Luis Hernández Yáñez

Página 42Fundamentos de la programación: Introducción a la recursión

Recursiónanidada:losnúmerosdeAckermann...int ackermann(int m, int n) {

int resultado;if (m == 0) 

resultado = n + 1;else if (n == 0)

resultado = ackermann(m ‐ 1, 1);else

resultado = ackermann(m ‐ 1, ackermann(m, n ‐ 1));return resultado;

}

int main() {int m, n;cout << "M = "; cin >> m;cout << "N = "; cin >> n;cout << ackermann(m, n) << endl;return 0;

}

Ack(m‐1,1) sim>0yn=0Ack(m,n)=

n+1 sim=0

Ack(m‐1,Ack(m,n‐1)) sim>0yn>0

ackermann.cpp

Pruébaloconnúmerosmuybajos:

SegeneranMUCHASllamadasrecursivas

Luis Hernández Yáñez

Página 43Fundamentos de la programación: Introducción a la recursión

Recursiónanidada:losnúmerosdeAckermann

Ack(m‐1,1) sim>0yn=0

n+1 sim=0

Ack(m‐1,Ack(m,n‐1)) sim>0yn>022

33

ackermann(1, 1)

ackermann(0, ackermann(1, 0))

ackermann(0, 1)

ackermann(0, 2)

Page 23: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

23

Luis Hernández Yáñez

Página 44Fundamentos de la programación: Introducción a la recursión

Recursiónanidada:losnúmerosdeAckermann

Ack(m‐1,1) sim>0yn=0

n+1 sim=0

Ack(m‐1,Ack(m,n‐1)) sim>0yn>033

55

4455

ackermann(2, 1)

ackermann(1, ackermann(2, 0))

ackermann(1, 1)

ackermann(1, 3)

ackermann(0, ackermann(1, 2))

ackermann(0, ackermann(1, 1))

ackermann(0, 3)

ackermann(0, 4)

2233

ackermann(0, ackermann(1, 0))

ackermann(0, 1)

ackermann(0, 2)

2233

ackermann(0, ackermann(1, 0))

ackermann(0, 1)

ackermann(0, 2)

Luis Hernández Yáñez

Página 45Fundamentos de la programación: Introducción a la recursión

RecursióncruzadaoindirectaLarecursióncruzadaoindirectasedacuandounafunciónllamaaotrayéstaasuvezllamaalaprimera.Porejemplo,sabersiunnúmeroesparoimpar:bool par(int n) {

if (n == 0) return true;else return impar(n – 1);

}

bool impar(int n) {if (n == 0) return false;else return par(n – 1);

}

int main() {int x;cout << "Num: "; cin >> x;if (par(x)) cout << "Es par";else cout << "Es impar";...

par.cpp

Page 24: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

24

Luis Hernández Yáñez

Página 46Fundamentos de la programación: Introducción a la recursión

Luis Hernández Yáñez

Página 47Fundamentos de la programación: Introducción a la recursión

CódigoanterioryposterioralallamadarecursivaEngeneral,enunsubprogramarecursivotendremosuncódigoanterioralallamadarecursivayuncódigoposterior:

{CódigoanteriorLlamadarecursivaCódigoposterior

}

Elcódigoanterior seejecutarárepetidasvecesparalasdistintasentradasantesdequesellegueaejecutarcualquiercódigoposterior.Ésteseejecutarárepetidasvecesparalasdistintasentradastrasllegaralcasobase.Sinohaycódigoanterior,tenemosrecursiónpordelante.

Elcódigoanteriorseejecutaenordendirectoparalasdistintasentradas,mientrasqueelcódigoposteriorlohaceenordeninverso.Sinohaycódigoposterior,tenemosrecursiónpordetrás.

Page 25: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

25

Luis Hernández Yáñez

Página 48Fundamentos de la programación: Introducción a la recursión

Códigoanterioryposterioralallamadarecursivavoid func(int n) {

if (n > 0) {cout << "Entrando (" << n << ")" << endl; // Código anteriorfunc(n ‐ 1);                              // Llamada recursivacout << "Saliendo (" << n << ")" << endl; // Código posterior

}}

Sillamamosalafunciónconelargumento5,lasalidaserá:

Elcódigoanterioralallamadaseejecutaparalosdistintosvaloresquevatomandon.Elcódigoposterioralallamada,alrevés.

Luis Hernández Yáñez

Página 49Fundamentos de la programación: Introducción a la recursión

Recorridodeloselementosdeunalista(directo)Conelcódigoanterioralallamadaprocesamosloselementosenelmismoordenenqueseencuentran:...void mostrar(tLista lista, int pos);

int main() {tLista lista;lista.cont = 0;// Carga del array...mostrar(lista, 0);

return 0;}

void mostrar(tLista lista, int pos) {if (pos < lista.cont) {

cout << lista.elementos[pos] << endl;mostrar(lista, pos + 1);

}}

directo.cpp

Page 26: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

26

Luis Hernández Yáñez

Página 50Fundamentos de la programación: Introducción a la recursión

Recorridodeloselementosdeunalista(inverso)Conelcódigoposterioralallamadaprocesamosloselementosenelordeninversoenqueseencuentran:...void mostrar(tLista lista, int pos);

int main() {tLista lista;lista.cont = 0;// Carga del array...mostrar(lista, 0);

return 0;}

void mostrar(tLista lista, int pos) {if (pos < lista.cont) {

mostrar(lista, pos + 1);cout << lista.elementos[pos] << endl;

}}

inverso.cpp

Luis Hernández Yáñez

Página 51Fundamentos de la programación: Introducción a la recursión

Page 27: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

27

Luis Hernández Yáñez

Página 52Fundamentos de la programación: Introducción a la recursión

ParámetrosporvaloryporreferenciaEnlossubprogramasrecursivoslosparámetrosporvalorsondatosqueelsubprogramanecesitapararealizarsusoperaciones.(Encadallamadarecursivapuedenserdistintos.)Losparámetrosporreferenciasonresultadosquesevanconstruyendoalolargodelasdistintasllamadas(mismavariableenlasllamadas):

void factorial(int n, int &fact) {if (n == 0) fact = 1;else {

factorial(n ‐ 1, fact);fact = n * fact;

}}

Enlallamadaafactorial(0),fact tomaelvalor1.Alavuelta,selemultiplicaporeln delallamadaanterior(1).Yalavuelta,poreln delallamadaanterior(2).Yasísucesivamente...

Luis Hernández Yáñez

Página 53Fundamentos de la programación: Introducción a la recursión

Page 28: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

28

Luis Hernández Yáñez

Página 54Fundamentos de la programación: Introducción a la recursión

BúsquedabinariaLabúsquedabinariaesunejemplodealgoritmoquetrabajapartiendoelproblemaensubproblemasmáspequeñosyaplicandoelmismoprocesoacadasubproblema.

Esarepetición delprocesoparacadasubproblemamuestraunanaturalezarecursivaquenospermiteimplementarlaasí.Partimosdelalistacompletaenlaquehayquebuscar.Sinoquedalista...terminar(listavacía:noencontrado)Encasocontrario...

Comprobarsielelementoenlamitadeselbuscado.Sieselbuscado...terminar(encontrado).Sino...

Sielbuscadoesmenorqueelelementomitad...Quedarseconlaprimeramitaddelalistayrepetirelproceso

Sielbuscadoesmayorqueelelementomitad...Quedarseconlasegundamitaddelalistayrepetirelproceso

Luis Hernández Yáñez

Página 55Fundamentos de la programación: Introducción a la recursión

BúsquedabinariaAcadaejecucióndelafunciónselepasandosíndicesqueindiquenlasposicionesinicialyfinaldelasublistaaprocesardentrodelalista:

int buscar(tLista lista, int buscado, int ini, int fin)// Devuelve la posición donde está (0, ...) o ‐1 si no está

¿Cuálessonloscasosbase?

Queyanoquedesublista(ini > fin) Noencontrado

Queseencuentreelelemento

RepasacómofuncionaycómoseimplementólabúsquedabinariaenelTema7(implementacióniterativa).

Page 29: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

29

Luis Hernández Yáñez

Página 56Fundamentos de la programación: Introducción a la recursión

Búsquedabinaria

int buscar(tLista lista, int buscado, int ini, int fin) {int pos = ‐1;if (ini <= fin) {

int mitad = (ini + fin) / 2;if (buscado == lista.elementos[mitad])

pos = mitad;else

if (buscado < lista.elementos[mitad])pos = buscar(lista, buscado, ini, mitad ‐ 1);

elsepos = buscar(lista, buscado, mitad + 1, fin);

}return pos;

}

1ªllamada:pos = buscar(lista, buscado, 0, lista.cont ‐ 1);

binaria.cpp

Luis Hernández Yáñez

Página 57Fundamentos de la programación: Introducción a la recursión

Búsquedabinaria:implementaciónconparámetrosdesalida

void buscar(tLista lista, int buscado, int ini, int fin,bool & encontrado, int & pos) {

if (ini > fin)  encontrado = false; else {   

int mitad = (ini + fin) / 2;if (buscado == lista.elementos[mitad]) {

encontrado= true; pos = mitad;

}//ifelse {

if (buscado < lista.elementos[mitad])buscar(lista, buscado, ini, mitad ‐ 1, encontrado, pos);

elsebuscar(lista, buscado, mitad + 1, fin, encontrado, pos);

}//else}//else

}

1ªllamada:buscar(lista, buscado, 0, lista.cont ‐ 1, enc, i);

Pedro J. M

artín de la Calle

Pedro J. M

artín de la Calle

Page 30: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

30

Luis Hernández Yáñez

Página 58Fundamentos de la programación: Introducción a la recursión

LastorresdeHanoiCuentaunaleyendaqueenuntemplodeHanoisedispusierontrespilaresdediamanteyenunodeellos64discosdeoro,dedistintosradiosycolocadosporordendetamañoconelmayordebajo.

Cadamonje,ensuturno,debíamoverunúnicodiscodeunpilaraotro,deformaqueentretodosconsiganconeltiempollevarlatorredelpilarinicialaunodelosotrosdos.Debíanrespetarunaregla:nuncaponerundiscosobreotrodemenortamaño.Cuandolohayanconseguido,seacabaráelmundo.

[Serequierenalmenos264‐1movimientos;sisehicieraunoporsegundo,seterminaríaenmásde500milmillonesdeaños.]

Torredeochodiscos(wikipedia.org)Torredeochodiscos(wikipedia.org)

Luis Hernández Yáñez

Página 59Fundamentos de la programación: Introducción a la recursión

LastorresdeHanoiQueremosintentarresolvereljuego enelmenornúmerodemovimientosposible.

¿Quédiscohayquemoverencadapasoyadóndehayquemoverlo?

Primero,identifiquemosloselementos(torredecuatrodiscos):

Cadapilarseidentificaconunaletra.

MoverdelpilarXalpilarYsignificarácogereldiscosuperiordeXyponerloencimadelosquehayaenY.

AA BB CC

Page 31: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

31

Luis Hernández Yáñez

Página 60Fundamentos de la programación: Introducción a la recursión

LastorresdeHanoiDebemosenfocarlaresolucióndelproblemaenbaseaproblemasmáspequeños.

MoverNdiscosdelpilarAalpilarC:

MoverN‐1discosdelpilarAalpilarB

MovereldiscodelpilarAalpilarC

MoverN‐1discosdelpilarBalpilarC

ParallevarNdiscosdeunpilarorigenaotropilardestino seutilizaeltercerpilarcomoauxiliar:

MoverN‐1discosdelorigen alauxiliar

Movereldiscodelorigen aldestino

MoverN‐1discosdelauxiliar aldestino

AA BB CC

AA BB CC

AA BB CC

AA BB CC

Mover4discosdeAa CMover4discosdeAa C

Luis Hernández Yáñez

Página 61Fundamentos de la programación: Introducción a la recursión

LastorresdeHanoiMoverN‐1discosdeunpilaraotroserealizadelamismaforma,peroutilizandoahoraotrospilarescomoorigenydestino.

MoverN‐1discosdelpilarAalpilarB:

MoverN‐2discosdelpilarAalpilarC

MovereldiscodelpilarAalpilarB

MoverN‐2discosdelpilarCalpilarB

Claramentesepuederesolverfácilmenteconunaimplementaciónrecursiva.

AA BB CC

AA BB CC

AA BB CC

AA BB CC

Simulaciónpara4discos(wikipedia.org)Simulaciónpara4discos(wikipedia.org)

Mover3discosdeAa BMover3discosdeAa B

Page 32: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

32

Luis Hernández Yáñez

Página 62Fundamentos de la programación: Introducción a la recursión

LastorresdeHanoiCasobase:noquedandiscosquemover....void hanoi(int n, char origen, char destino, char auxiliar) {

if (n == 0) return;else {

hanoi(n ‐ 1, origen, auxiliar, destino);cout << origen << " ‐‐> " << destino << endl;hanoi(n ‐ 1, auxiliar, destino, origen);

}}

int main() {int n;cout << "N. torres: "; cin >> n;hanoi(n, 'A', 'B', 'C');

return 0;}

hanoi.cpp

Luis Hernández Yáñez

Página 63Fundamentos de la programación: Introducción a la recursión

Page 33: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

33

Luis Hernández Yáñez

Página 64Fundamentos de la programación: Introducción a la recursión

¿Quéespreferible?Cualquieralgoritmorecursivosepuedetraduciraunalgoritmoiterativoquerealiceelmismotrabajo.

Losalgoritmosrecursivossonmenoseficientesquesusalternativasiterativas:sobrecargadelasllamadasalossubprogramas.

Siemprequeresultesencillodesarrollarunaversióniterativa,éstaserápreferibleasuversiónrecursiva.

Peroenocasionesnoresultasencilloobteneresaversióniterativaequivalente,siendolaversiónrecursivamuchomássimple.Enestoscasosserápreferiblelaversiónrecursiva(sielrendimientonoesunfactorclave).

DesarrollaversionesiterativasdelfactorialodelosnúmerosdeFibonacci.¿YquétalconlosnúmerosdeAckermann?

Luis Hernández Yáñez

Página 65Fundamentos de la programación: Introducción a la recursión

Page 34: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

34

Luis Hernández Yáñez

Página 66Fundamentos de la programación: Introducción a la recursión

DefiniciónrecursivadelistasYahemosdefinidodeformarecursivaalgunaestructuradedatos:

Laslistastambiénsepuedendefinirdeformasimilar:

Lalista1,2,3consisteenelelemento1seguidodelalista2,3,que,asuvez,consisteenelelemento2seguidodelalista3,que,asuvez,consisteenelelemento3seguidodelalistavacía(casobase).Hayotrasestructurasconnaturalezarecursiva(comolosárboles)queestudiarásenposteriorescursos.

secuenciavacía(ningúnelemento)Secuencia=

elementoseguidodeunasecuencia

listavacía(ningúnelemento) (Casobase)Lista=

elementoseguidodeunalista

Luis Hernández Yáñez

Página 67Fundamentos de la programación: Introducción a la recursión

ProcesamientodeestructurasrecursivasLanaturalezarecursivadealgunasestructurasdedatosllevadeformanaturalaunprocesamientorecursivodelasmismas:

Procesar(lista):

Silistanovacía(casobase):

Procesarelprimerelementodelalista//Códigoanterior

Procesar(resto(lista))

Procesarelprimerelementodelalista//Códigoposterior

Donderesto(lista) devuelveunalistaigualalaqueseproporcionasinsuprimerelemento.

Page 35: New Fundamentos programación 2013 10 - Academia Cartagena99 · 2014. 7. 13. · La pila del sistema 10 La pila y las llamadas a función 11 Ejecución de la función factorial()

23/05/2014

35

Luis Hernández Yáñez

C++:An Introduction to Computing (2ªedición)J.Adams,S.Leestma,L.Nyhoff.Prentice Hall,1998

EllenguajedeprogramaciónC++ (Ediciónespecial)B.Stroustrup.Addison‐Wesley,2002

ProgramaciónenC++paraingenierosF.Xhafa etal.Thomson,2006

Fundamentos de la programación: Introducción a la recursión Página 68

Luis Hernández Yáñez

LicenciaCC(Creative Commons)Estetipodelicenciasofrecenalgunosderechosaterceraspersonasbajociertascondiciones.

Estedocumentotieneestablecidaslassiguientes:

Pulsaenlaimagendearribaaladerechaparasabermás.

Fundamentos de la programación: Introducción a la recursión Página 69

Reconocimiento(Attribution):Encualquierexplotacióndelaobraautorizadaporlalicenciaharáfaltareconocerlaautoría.

Nocomercial(Noncommercial):Laexplotacióndelaobraquedalimitadaausosnocomerciales.

Compartirigual(Sharealike):Laexplotaciónautorizadaincluyelacreacióndeobrasderivadassiemprequemantenganlamismalicenciaalserdivulgadas.