Ejercicios: Recursividad y Divide y Vencerás Universidad Nacional de Río Negro
Ejercicios de Recursividad y Divide y Vencerás ¶ Acerca de ¶ Estos ejercicios tienen como propósito dominar la recursividad de control y el
paradigma de diseño “Divide y Vencerás” en C.
Capítulos de Apunte Correspondientes ¶ Cuestiones de Estilo Aplicables ¶ Casos de corte explícitos: Definí el caso base al inicio de la función
recursiva para evitar lazo de llamada infinitos y desbordamientos de stack
frame (ver Regla 0x2009h: Los ejercicios deben ser resueltos mediante funciones ).
Uso de recursión de cola: Cuando sea posible, estructurá las funciones
recursivas utilizando parámetros acumuladores para permitir la optimización
por parte del compilador.
Fundamentos de Recursividad ¶ Ejercicio 29.1 - Factorial ⭐⭐☆☆☆ ¶ Implementar la función factorial de forma recursiva siguiendo la definición
matemática.
[plus ultra ]: Diseñar la función para devolver un código de estado de
error e informar el resultado mediante parámetros de salida.
[plus ultra ]: Documentar la función con etiquetas Doxygen
especificando precondiciones y postcondiciones.
long int factorial(int n);Definición recursiva:
n ! = { 1 si n = 0 n × ( n − 1 ) ! si n > 0 n! = \begin{cases}
1 & \text{si } n = 0 \\
n \times (n-1)! & \text{si } n > 0
\end{cases} n ! = { 1 n × ( n − 1 )! si n = 0 si n > 0 Casos de prueba:
factorial(0) → 1
factorial(5) → 120
factorial(10) → 3628800
Ejercicio 29.2 - Suma de Enteros ⭐⭐☆☆☆ ¶ Implementar suma de dos enteros positivos usando solo recursividad (sin operador
+ en el paso recursivo).
[plus ultra ]: Garantizar la terminación con \0 y prevenir
desbordamientos de búfer validando la capacidad máxima.
[plus ultra ]: Soportar la lectura de cadenas con espacios y múltiples
líneas de manera robusta.
int suma_recursiva(int a, int b);Estrategia: Decrementar b e incrementar a hasta que b sea 0.
s u m a ( a , b ) = { a si b = 0 s u m a ( a + 1 , b − 1 ) si b > 0 suma(a, b) = \begin{cases}
a & \text{si } b = 0 \\
suma(a + 1, b - 1) & \text{si } b > 0
\end{cases} s u ma ( a , b ) = { a s u ma ( a + 1 , b − 1 ) si b = 0 si b > 0 Ejercicio 29.3 - Producto por Sumas Recursivas ⭐⭐☆☆☆ ¶ Implementar multiplicación usando solo sumas recursivas.
[plus ultra ]: Transformar el algoritmo a una versión con recursión de
cola (tail recursion ) para reducir el consumo de pila.
[plus ultra ]: Añadir un contador del número de llamadas recursivas
realizadas para analizar la complejidad empírica.
int producto_recursivo(int a, int b);a × b = { 0 si b = 0 a + p r o d u c t o ( a , b − 1 ) si b > 0 a \times b = \begin{cases}
0 & \text{si } b = 0 \\
a + producto(a, b - 1) & \text{si } b > 0
\end{cases} a × b = { 0 a + p ro d u c t o ( a , b − 1 ) si b = 0 si b > 0 Complejidad: O ( b ) O(b) O ( b ) en tiempo.
Ejercicio 29.4 - Potencia ⭐⭐☆☆☆ ¶ Implementar b a s e e x p o n e n t e base^{exponente} ba s e e x p o n e n t e de forma recursiva.
[plus ultra ]: Validar estrictamente los datos de entrada para manejar
valores fuera de rango o tipos inválidos.
[plus ultra ]: Permitir el procesamiento interactivo continuo mediante
un lazo hasta que el usuario elija finalizar.
long int potencia(int base, int exponente);Versión básica: O ( n ) O(n) O ( n ) en tiempo.
b a s e e x p = { 1 si e x p = 0 b a s e × p o t e n c i a ( b a s e , e x p − 1 ) si e x p > 0 base^{exp} = \begin{cases}
1 & \text{si } exp = 0 \\
base \times potencia(base, exp - 1) & \text{si } exp > 0
\end{cases} ba s e e x p = { 1 ba se × p o t e n c ia ( ba se , e x p − 1 ) si e x p = 0 si e x p > 0 Desafío: Implementar versión optimizada usando exponenciación rápida (divide
y vencerás) con complejidad O ( log n ) O(\log n) O ( log n ) .
b a s e e x p = { 1 si e x p = 0 ( b a s e e x p / 2 ) 2 si e x p es par b a s e × ( b a s e ( e x p − 1 ) / 2 ) 2 si e x p es impar base^{exp} = \begin{cases}
1 & \text{si } exp = 0 \\
\left(base^{exp/2}\right)^2 & \text{si } exp \text{ es par} \\
base \times \left(base^{(exp-1)/2}\right)^2 & \text{si } exp \text{ es impar}
\end{cases} ba s e e x p = ⎩ ⎨ ⎧ 1 ( ba s e e x p /2 ) 2 ba se × ( ba s e ( e x p − 1 ) /2 ) 2 si e x p = 0 si e x p es par si e x p es impar Series Numéricas Recursivas ¶ Ejercicio 29.5 - Fibonacci Básico ⭐☆☆☆☆ ¶ Implementar la secuencia de Fibonacci recursivamente.
[plus ultra ]: Validar estrictamente los datos de entrada para manejar
valores fuera de rango o tipos inválidos.
[plus ultra ]: Permitir el procesamiento interactivo continuo mediante
un lazo hasta que el usuario elija finalizar.
long int fibonacci(int n);Ecuación de recurrencia:
F ( n ) = { 0 si n = 0 1 si n = 1 F ( n − 1 ) + F ( n − 2 ) si n > 1 F(n) = \begin{cases}
0 & \text{si } n = 0 \\
1 & \text{si } n = 1 \\
F(n-1) + F(n-2) & \text{si } n > 1
\end{cases} F ( n ) = ⎩ ⎨ ⎧ 0 1 F ( n − 1 ) + F ( n − 2 ) si n = 0 si n = 1 si n > 1