Update PEC 7

This commit is contained in:
Manuel Vergara 2024-06-27 20:27:23 +02:00
parent d24a4359ba
commit 29f903b286

View File

@ -10,10 +10,95 @@
## 20. Recursividad ## 20. Recursividad
El concepto de recursividad hace referencia a que un algoritmo se utilice a sí mismo para resolver un problema. En programación, la recursividad se utiliza para resolver problemas que pueden ser descompuestos en problemas más pequeños del mismo tipo. La recursividad es una técnica muy potente, pero también puede ser peligrosa si no se utiliza correctamente, ya que puede llevar a que un programa se ejecute indefinidamente.
### 20.1. Ejemplo: números naturales ### 20.1. Ejemplo: números naturales
Los número naturales tienen su definición revursiva en matemáticas:
- 0 ∈ N
- Si n ∈ N, entonces n+1 ∈ N
El conjunto de números naturales es el mínimo conjunto que cumple estas dos propiedades.
En este caso vemos que para definir qué es un número natural, lo hacemos recursivamente, o sea, a partir de saber que n es recursivo, sabemos que n + 1 también lo es. Con lo cual, lo podemos ver en el siguiente algoritmo:
```alg
function isNatural(n: integer): boolean
var
result: boolean
end var
if n = 0 then
result := true
else
result := isNatural(n - 1)
end if
return result
end function
```
```c
#include <stdbool.h>
bool isNatural(int n) {
if (n == 0) {
result = true;
} else {
result = isNatural(n - 1);
}
return result;
}
```
En este código vemos un ejemplo de los dos elementos que todo algoritmo recursivo debe tener:
- Condición de finalización (en este caso cuando n es 0)
- Regla recursiva (una llamada recursiva con n-1)
En la siguiente figura se puede ver la simulación de lo que pasaría en la memoria cuando se llama `isNatural(2)`.
step 1 - Veremos que cuando se llama isNatural con el valor 2, este queda guardado en una zona de memoria.
```
| ... | 32 | 33 | 34 | 35 | ... | 65 | 66 | 67 | 68 | ... | 215 | 216 | 217 | 218 | ... |
|-----|----|----|----|-----|-----|----|----|----|----|-----|-----|-----|-----|-----|-----|
| ... | 2 | ... | | | | | ... | | | | | ... |
```
step 2 - Siguiendo con el algoritmo, ya que n no es 0, se hace otra llamada a isNatural con el valor 1. Esta nueva llamada se añade a la pila y queda guardada en otra zona de memoria diferente. Como n todavía no es 0, se vuelve a hacer una llamada a isNatural con el valor 0 y esta nueva llamada también queda añadida a la pila utilizando otra zona de memoria.
```
| ... | 32 | 33 | 34 | 35 | ... | 65 | 66 | 67 | 68 | ... | 215 | 216 | 217 | 218 | ... |
|-----|----|----|----|-----|-----|----|----|----|----|-----|-----|-----|-----|-----|-----|
| ... | 2 | ... | 1 | ... | | | | | ... |
```
step 3 - En este caso, como el parámetro tiene valor 0, se devolverá un true y se finalizará esta llamada.
```
| ... | 32 | 33 | 34 | 35 | ... | 65 | 66 | 67 | 68 | ... | 215 | 216 | 217 | 218 | ... |
|-----|----|----|----|-----|-----|----|----|----|----|-----|-----|-----|-----|-----|-----|
| ... | 2 | ... | 1 | ... | 0 | ... |
```
step 4 - Cuando se finaliza la ejecución de una acción o función, toda la memoria ocupada por sus parámetros y variables se elimina y, por lo tanto, ahora solo quedarán las dos llamadas iniciales a la memoria.
```
| ... | 32 | 33 | 34 | 35 | ... | 65 | 66 | 67 | 68 | ... | 215 | 216 | 217 | 218 | ... |
|-----|----|----|----|-----|-----|----|----|----|----|-----|-----|-----|-----|-----|-----|
| ... | 2 | ... | 1 | ... | | | | | ... |
```
step 5 - La segunda llamada devolverá el valor true que ha devuelto la última llamada y, por tanto, finalizará y quedará solo la primera llamada a la memoria. Finalmente esta llamada inicial retornará y también se eliminará de la memoria.
```
| ... | 32 | 33 | 34 | 35 | ... | 65 | 66 | 67 | 68 | ... | 215 | 216 | 217 | 218 | ... |
|-----|----|----|----|-----|-----|----|----|----|----|-----|-----|-----|-----|-----|-----|
| ... | 2 | ... | | | | | ... | | | | | ... |
| n | ... | n | ... | n | ... |
```
Lo importante es ver que, aunque sea la misma función, a efectos prácticos es como si se tratara de funciones diferentes y, por tanto, los parámetros y variables que tenga son independientes entre llamadas.
### 20.2. Ejemplo: factorial ### 20.2. Ejemplo: factorial