SlideShare una empresa de Scribd logo
1 de 18
Descargar para leer sin conexión
Diseño de estructuras de datos y algoritmos 1
Capítulo 3
Algoritmos recursivos
Los algoritmos recursivos se basan en la metodología de llamar
repetidamente la propia función en que están definidos, y son de gran utilidad en
multitud de campos en la informática.
Al finalizar el estudio de estas lecciones serás capaz de:
Conocer los fundamentos y características de los algoritmos recursivos.
Conocer el funcionamiento de las funciones recursivas.
Conocer las características fundamentales de las estructuras de datos
recursivas.
Conocer las ventajas y desventajas de las funciones recursivas frente a las
funciones iterativas.
Diseño de estructuras de datos y algoritmos 2
Lección 1
Algoritmos recursivos
Introducción
Una técnica común de resolución de problemas es la división de un problema
en varios subproblemas de la misma categoría, pero de más fácil resolución. Esta
técnica se conoce como divide y vencerás.
Un ejemplo de algoritmos en los que se aplica esta técnica son los
algoritmos recursivos, en los cuales el algoritmo se llama a sí mismo
repetidamente, procurando simplificar o reducir el problema en cada llamada, hasta
llegar a un caso trivial de solución directa.
La mayoría de los lenguajes soportan los algoritmos recursivos, permitiendo
que una función se llame a sí misma. En un algoritmo recursivo, los bucles típicos
de un algoritmo iterativo (para..hasta, mientras…) se sustituyen por llamadas al
propio algoritmo.
Al escribir un algoritmo recursivo, debe establecerse de algún modo cuando
debe dejar de llamarse a sí mismo, o de otra forma se repetiría indefinidamente.
Para ello, se establece una condición de salida llamada caso base.
La recursividad es una técnica de programación que
busca resolver un problema sustituyéndolo por otros
problemas de la misma categoría, pero más simples.
Se dice que un algoritmo es recursivo si dentro del
cuerpo del algoritmo y de forma directa o indirecta se
realiza una llamada a él mismo.
Diseño de estructuras de datos y algoritmos 3
El caso base contempla el caso en el cual la solución es lo suficientemente
sencilla como para responder directamente sin necesidad de realizar otra llamada al
algoritmo.
El ejemplo más típico de algoritmo recursivo es el de una
función para calcular el factorial de un número. El factorial de
un número es el resultado de multiplicar dicho número por todos los
precedentes, hasta llegar a 1. Por ejemplo, factorial(3) = 3 * 2 * 1.
Si observamos que el factorial de un número es equivalente al
producto de dicho número por el factorial del número precedente:
factorial(3) = 3 * factorial(2)
podemos plantear una implementación recursiva:
función factorial(n)
si n = 1
devolver 1
sino
devolver n * factorial(n – 1)
fin si
fin función
En este caso, la sentencia
si n = 1 devolver 1
es la condición de salida o caso base que evita que la función se
llame a sí misma indefinidamente.
Todo algoritmo recursivo debe incluir al menos un
caso base y garantizar que se ejecuta en algún
momento para evitar la recursividad infinita.
Se llama caso base o condición de salida al caso trivial
de un algoritmo recursivo, del cual conocemos su
solución.
Diseño de estructuras de datos y algoritmos 4
El concepto de recursividad pone una gran potencia al alcance del
programador y adquiere una dimensión fundamental en los llamados lenguajes de
programación funcionales, los cuales a menudo no incorporan sentencias que
permitan crear bucles, debiendo recurrir a las llamadas recursivas para
implementar repeticiones.
Se pueden establecer diferentes categorías de recursividad en virtud de la
característica del algoritmo analizada:
▪ Según el punto desde el cual se hace la llamada recursiva: recursividad
directa o indirecta.
▪ Según el número de llamadas recursivas efectuadas en tiempo de
ejecución: recursividad lineal o no lineal.
▪ Según el punto del algoritmo desde donde se efectúa la llamada recursiva:
recursividad final o no final.
Para obtener más información respecto a los lenguajes de
programación funcionales, consulta la dirección Web
http://es.wikipedia.org/wiki/Programaci%C3%B3n_funcional
La mayoría de los algoritmos que pueden ser descritos de
forma iterativa (es decir, haciendo uso de bucles while,
for…) pueden ser reescritos de forma recursiva, y
viceversa.
Al hablar de funciones recursivas, nos referimos a algoritmos
recursivos implementados en un lenguaje particular. Aunque
hemos elegido el término genérico función, pueden
emplearse otros similares como procedimiento o método.
Diseño de estructuras de datos y algoritmos 5
Recursividad directa y recursividad indirecta
▪ Recursividad directa: Se da cuando la función efectúa una llamada a sí
misma.
▪ Recursividad indirecta: Se da cuando una función A llama a otra función
B la cual a su vez, y de forma directa o indirecta, llama nuevamente a A.
Recursividad lineal y recursividad no lineal
▪ Recursividad lineal o simple: Se da cuando la recursividad es directa y
además cada llamada a la función recursiva sólo hace una nueva llamada
recursiva.
▪ Recursividad no lineal o múltiple: La ejecución de una llamada
recursiva da lugar a más de una llamada a la función recursiva.
función A
…
si condición
A(…)
fin si
…
A(…)
…
fin función
La recursividad será no
lineal si se cumple
condición, pues en tal
caso se producen dos
llamadas recursivas.
función A
…
A(…)
…
fin función
función A
…
A(…)
…
fin función
función A
…
B(…)
…
fin función
función B
…
A(…)
…
fin función
Diseño de estructuras de datos y algoritmos 6
Recursividad final y recursividad no final
▪ Recursividad final: Se da cuando la llamada recursiva es la última
operación efectuada en el cuerpo de la función. (sin tener en cuenta la
sentencia devolver)
▪ Recursividad no final: Se da cuando la llamada recursiva no es la última
operación realizada dentro de la función (sin tener en cuenta la sentencia
devolver)
función A
…
devolver A(…) + 5
fin función
La llamada a la función
recursiva no es la última
operación efectuada (en
ambos casos es una
suma)
función A
…
devolver A(…) + A(…)
fin función
función A
…
devolver A(…)
fin función
No existe ningún
procesamiento posterior
a la llamada a A().
Explicaremos más a fondo la recursividad final en la Lección 4 –
Funciones recursivas finales.
La secuencia de Fibonacci, definida por la fórmula
fib(n) = n si n = 0 o si n = 1
fib(n) = fib(n – 2) + fib(n – 1) si n >= 2
es un ejemplo de recursividad múltiple y no final. Para el caso
n>=2 se producen dos llamadas recursivas, y al regresar de la
llamada recursiva el resultado no se devuelve tal cual sino que
se suma con el resultado de otra llamada recursiva.
Diseño de estructuras de datos y algoritmos 7
Diseño de funciones recursivas
Para escribir un algoritmo de forma recursiva es necesario intentar
transformar el problema en otro similar pero más simple, así como encontrar una
solución directa para los casos triviales.
Es necesario, pues:
▪ Identificar y formular el caso base o condición de salida del cual
conocemos la solución directamente.
▪ Formular el caso general que debe poder resolverse en función del caso
base y una transformación del caso general hacia uno más sencillo.
Diseño de estructuras de datos y algoritmos 8
Lección 2
Mecanismo de recursividad
La pila de llamadas
Para comprender el funcionamiento de un algoritmo recursivo es
fundamental conocer como funciona la pila de llamadas de un programa en
ejecución.
Todo programa en ejecución tiene una pila asociada para éste propósito. En
los lenguajes de alto nivel (como C o Java) la gestión de la pila de llamadas la
realiza de forma automática el compilador, y el programador no necesita
preocuparse de su funcionamiento.
Cuando en un punto concreto de un programa se llama a una función -sea
recursiva o no- se reserva espacio en la pila para la siguiente información:
▪ La dirección de retorno de la función:
De modo que sea posible regresar al punto de ejecución
inmediatamente posterior al de la llamada a la función.
▪ Los parámetros de la llamada:
La función llamada obtiene los parámetros (también llamados
argumentos) de la pila. Por ejemplo, en una función para sumar dos
números, los argumentos serían los números a sumar.
▪ Espacio para las variables locales
El compilador reserva espacio en la pila para almacenar las variables
locales. La cantidad de espacio reservado es proporcional al número
de variables locales definidas y al tamaño requerido por cada variable
(carácter, entero, real…).
▪ El resultado devuelto por la función
Opcionalmente, ya que también es posible y usual devolver el
resultado de la llama a la función en uno de los registros de la CPU.
Dependiendo del lenguaje de programación y arquitectura de ejecución
elegidos, suelen asignarse funciones extra a la pila de llamadas (por ejemplo, en
los lenguajes orientados a objetos a menudo también se almacena en la pila el
puntero al objeto cuyo método estamos llamando, “this”).
La pila de llamadas (call stack en inglés) es un
segmento de memoria basado en una estructura de
datos del tipo pila utilizada para almacenar información
relacionada con las llamadas a funciones dentro de un
programa.
Diseño de estructuras de datos y algoritmos 9
En el siguiente esquema se ejemplifica la ejecución de la función main() de
un programa. La columna dirección de memoria contiene la dirección de memoria
(hipotética) asignada a las diferentes sentencias del programa. Conforme una
función llama a otra, se almacenan los datos correspondientes en la pila:
Una vez una función regresa después de su ejecución, se descarta de forma
automática el espacio en la pila que se le había asignado. De esta forma, la pila va
creciendo y decreciendo.
Cuanto mayor es el nivel de anidamiento de llamadas a funciones, mayor es
el espacio de memoria ocupado en la pila, y existe incluso la posibilidad de ocupar
todo el espacio de memoria que tiene asignado. Este hecho se conoce como
desbordamiento de pila (stack overflow en inglés). Por esta razón es muy
importante evitar que una función recursiva se llame indefinidamente: no sólo el
programa se quedaría “colgado”, sino que saturaríamos por completo la memoria
destinada a la pila.
función main()
…
funciónA(5)
…
fin función
5
Pila
…
23
24
parámetro 5
dirección de memoria
…
función A()
…
funciónB(8,9)
…
fin función
60
…
67
68
80
…
24
8
9
68
Llamada a
funciónB
dirección de
crecimiento de
la pila
dir. retorno
Espacio variables
Llamada a
funciónA
función B()
…
fin función
Diseño de estructuras de datos y algoritmos 10
Llamadas recursivas
Una vez visto el funcionamiento básico de la pila de llamadas de un
programa, podemos estudiar el uso de la pila en una función recursiva con un
ejemplo. Para ello, seguiremos con el ejemplo del cálculo del factorial de un
número. El siguiente esquema muestra el uso de la pila que resulta de hacer una
llamada a la función factorial:
En cada llamada recursiva, se requiere espacio en la pila para almacenar
dirección de retorno, parámetros y resultado de la llamada. La pila crece hacia
arriba conforme se efectúan las llamadas: llamada principal, 1ª llamada recursiva,
2ª llamada recursiva y 3ª llamada recursiva (la final, que llega al caso base).
En el esquema anterior se han introducido en la pila los valores finales
devueltos por las llamadas recursivas, pero el espacio asignado en la pila para el
resultado de la llamada contiene un valor sin definir inicialmente.
La dirección de retorno es la misma en todos los casos, ya que la instrucción
siguiente a cada una de las llamadas es idéntica en todos los casos.
24
función factorial(n)
…
factorial(n - 1)
…
fin función
2
…
23
24
parámetro n
Llamada inicial: factorial(3)
…
2
24
1
1
24
2ª llamada
dir. retorno
resultado
1ª llamada
6
Llamada
principal
3
0
1
24
3ª llamada
Diseño de estructuras de datos y algoritmos 11
Conforme las llamadas devuelven su resultado, se libera el espacio asignado
en la pila para dicha llamada:
De este modo, tras la llamada factorial(3) la pila se encuentra de nuevo en
el estado en el que se encontraba justo antes de la llamada a la función.
datos llamada
principal
PILA
Paso 1
datos llamada
principal
PILA
Paso 2
datos 1ª llamada
recursiva
datos llamada
principal
PILA
Paso 3
datos 1ª llamada
recursiva
datos 2ª llamada
recursiva
datos llamada
principal
PILA
Paso 4
datos 1ª llamada
recursiva
datos 2ª llamada
recursiva
datos 3ª llamada
recursiva
datos llamada
principal
PILA
Paso 5
datos 1ª llamada
recursiva
datos 2ª llamada
recursiva
3ª llamada
devuelve 1
datos llamada
principal
PILA
Paso 6
datos 1ª llamada
recursiva
2ª llamada
devuelve 1
datos llamada
principal
PILA
Paso 7
1ª llamada
devuelve 2
PILA
Paso 8
llamada ppal.
devuelve 6
1
Escribe un algoritmo recursivo que calcule el elemento de
cardinal más elevado de un vector de datos de tipo
entero.
Por ejemplo, para la entrada {1, 3, 25, 9, 20} obtendremos
como resultado 25.
Diseño de estructuras de datos y algoritmos 12
2
El valor de xn
se puede definir recursivamente como:
x0
= 1
xn
= x * xn – 1
Implementa de forma recursivo el cálculo de xn
para
cualquier valor de X y n.
Diseño de estructuras de datos y algoritmos 13
Lección 3
Estructuras de datos recursivas
Introducción
A menudo encontramos problemas cuya información puede presentarse de
forma natural como una estructura de datos de tipo lista, pila, cola, árbol o grafo.
Dado que dichas estructuras de datos poseen en sí mismas carácter
recursivo (pues se incluyen a si mismas en su definición), resulta natural tratar
estos problemas con algoritmos recursivos.
Vamos a estudiar brevemente la aplicación del concepto de recursividad a
listas enlazadas y árboles. La extensión a otros tipos de estructuras de datos es
sencilla debido a su similitud (todas ellas incluyen referencias al siguiente o
siguientes elementos).
Listas enlazadas
En una estructura del tipo lista enlazada cada nodo contiene una referencia
al siguiente nodo (alternativamente es posible que contenga una referencia al nodo
anterior, en las listas doblemente encadenadas), y un conjunto de atributos extra
específicos del nodo en cuestión:
Una función que opere de forma recursiva sobre una lista enlazada, deberá
procesar el nodo actual y pasar como parámetro el nodo siguiente. La condición de
salida en este caso se dará cuando lleguemos a un nodo de valor null, que indicará
el final de la lista:
Árboles
En una estructura del tipo árbol cada nodo contiene una referencia a los
hijos izquierdo y derecho de la rama actual:
función procesaLista(nodo)
si nodo <> null
imprime(nodo.dato)
procesaLista(nodo.siguiente)
fin si
fin función
estructura Nodo
dato: entero
siguiente: Nodo
fin estructura
Diseño de estructuras de datos y algoritmos 14
El algoritmo se llama pasando como parámetro inicial el nodo raíz del árbol,
y las llamadas siguientes procesan los nodos hijos o subárboles del nodo principal,
hasta llegar al caso base, que en un árbol corresponde a un nodo que no tiene
nodos hijos, es decir, un nodo cuyos atributos hijoIzq e hijoDch son null. Estos
nodos reciben el nombre de hojas del árbol. En el caso de un árbol, se procesan
recursivamente tanto su lado izquierdo como su lado derecho:
función procesaArbol(nodo)
si nodo <> null
imprime(nodo.dato)
procesaArbol(nodo.hijoIzq)
procesaArbol(nodo.hijoIzq)
fin si
fin función
estructura Nodo
dato : entero
hijoIzq, hijoDch: Nodo
fin estructura
Diseño de estructuras de datos y algoritmos 15
Lección 4
Funciones recursivas finales
Funciones recursivas finales
En ocasiones se descarta el uso de funciones recursivas por el uso adicional
de memoria que a menudo requieren respecto a la versión iterativa del mismo
algoritmo. Cada llamada requiere espacio de pila para la dirección de retorno,
parámetros pasados, etc.
No obstante, existe un tipo de funciones recursivas, llamadas funciones
recursivas finales, en las cuales el tamaño de memoria de la pila utilizado no se ve
afectado por el nivel de profundidad de recursión alcanzado.
Para que una función recursiva sea final de pleno derecho, la llamada
recursiva a la función debe ser la última operación realizada:
Ejemplos___________________________________________________________
De las siguientes funciones recursivas, solo la última, recursiva3, es
recursiva final; en el resto se efectúan otras operaciones después de la llamada a la
función:
función recursivaA()
num := 10
recursivaA();
a = a + 4;
devolver num
fin función
función recursivaB()
int q = 4;
q = q + 5;
devolver q + test1()
fin función
función recursiva3 ()
int b = 5;
b = b + 2;
devolver recursiva3()
Se llama función recursiva final (tail-call recursive
function en inglés) a toda función recursiva cuya última
operación es la llamada recursiva en sí.
Diseño de estructuras de datos y algoritmos 16
fin función
__________________________________________________________________
Tras realizar la llamada recursiva la función ya no necesita del espacio en la
pila, puesto que:
- no va a hacer más uso de los parámetros pasados por la función
llamante y guardados en la pila
- no va a hacer más uso de variables locales
- no va a procesar el valor de retorno
Por tanto, el compilador puede incluir código que de forma automática
reutilice el espacio en pila reservado para la llamada a la función, de modo que sea
utilizado por la siguiente llamada. De este modo, la penalización en tiempo que
supone inicializar la pila para la siguiente llamada recursiva desaparece:
Simplemente es necesario escribir los nuevos valores de los parámetros sobre los
antiguos:
Con esta optimización, la eficiencia de una función recursiva se pone a la par
de la versión iterativa del mismo algoritmo.
24
función rec(n)
…
rec(n - 1)
fin función
…
23
24
parámetro n
Llamada inicial: rec(3)
…
dir. retorno
resultado
El parámetro se reescribe en cada
llamada
5
Pila
No todos los compiladores soportan la optimización
de funciones recursivas finales.
Diseño de estructuras de datos y algoritmos 17
Lección 5
Recursividad vs. iteración
Recursividad vs Iteración
La mayoría de los algoritmos pueden expresarse tanto de forma iterativa
como de forma recursiva. A la hora de implementar un algoritmo, surge la duda
respecto a la conveniencia de utilizar una versión u otra.
A menudo los programadores acostumbrados al uso de lenguajes
imperativos como C o Java descartan el uso de funciones recursivas, aludiendo a
razones de eficiencia o memoria. Sin embargo, dichas deficiencias pueden
minimarse a menudo.
Existen distintos factores a considerar; a continuación enumeramos los más
importantes:
▪ Conveniencia
- por el lenguaje de programación utilizado
Algunos lenguajes se benefician del uso de funciones recursivas
respecto a las funciones iterativas. Por ejemplo, los llamados lenguajes
funcionales, como Lisp, Scheme o Haskell, están orientados y optimizados
para el trabajo con funciones recursivas.
- por la definición del problema
Hay problemas cuya definición y/o solución son inherentemente
recursivas y una solución iterativa resultaría demasiado complicada. Lo
contrario también es posible.
▪ Eficiencia
En general la versión iterativa de una función siempre es más eficiente que
la versión recursiva, tanto en términos de velocidad de ejecución como de memoria
utilizada:
- Velocidad de ejecución:
En la versión recursiva, el hecho de que la función se llame a sí
misma incurre en tiempo extra de proceso: La llamada a una función supone
un coste extra en términos de tiempo de procesador en comparación con el
coste que supone reiniciar una nueva iteración de un bucle: es necesario
almacenar los parámetros pasados (si los hay) en la pila, así como la
dirección de retorno, etc.
Diseño de estructuras de datos y algoritmos 18
No obstante, si el compilador soporta las funciones recursivas finales
y podemos escribir el algoritmo como tal, la eficiencia se pone a la par de la
versión iterativa.
- Uso de memoria:
En la versión recursiva, la llamada a la función requiere del uso de la
pila para almacenar los parámetros pasados (si los hay), dirección de
retorno, resultado, etc. Si el nivel de recursión puede ser muy elevado, el
uso de memoria puede ser considerable o incluso prohibitivo.
No obstante, algunos algoritmos, en su versión iterativa, requieren de
estructuras de datos auxiliares que son implícitas a la versión recursiva del
algoritmo al pasar los datos como parámetros en la pila, de modo que
consumen también mucha memoria, al nivel de la versión recursiva.
▪ Sencillez
En ocasiones es mucho más sencillo escribir la versión recursiva de un
algoritmo que la versión iterativa, y viceversa. La elección de una u otra alternativa
puede basarse en este hecho.
En general, la versión recursiva de una función es mucho más elegante y
sencilla a nivel de cantidad de código requerido que la versión iterativa.
▪ Intuitividad
El planteamiento iterativo de una función resulta a menudo más intuitivo
que el recursivo, y viceversa. Es posible favorecer la legibilidad y comprensibilidad
del código respecto a la eficiencia si ésta no es un factor determinante.
De forma general, si la eficiencia es un factor importante y/o
el algoritmo se va a ejecutar de forma frecuente, conviene
escribir una solución iterativa.
1
Reescribe el algoritmo para calcular el factorial de un
número de forma iterativa.

Más contenido relacionado

La actualidad más candente

Teoría de optimización
Teoría de optimizaciónTeoría de optimización
Teoría de optimizaciónAngel Jhoan
 
Maquina de turing y resolubilidad e Irresolubilidad
Maquina de turing y resolubilidad e IrresolubilidadMaquina de turing y resolubilidad e Irresolubilidad
Maquina de turing y resolubilidad e Irresolubilidadlluis31
 
Algebra relacional
Algebra relacionalAlgebra relacional
Algebra relacionalclaudyabra
 
Máquinas de turing y autómatas acotados
Máquinas de turing y autómatas acotadosMáquinas de turing y autómatas acotados
Máquinas de turing y autómatas acotadosBryan Chasiguano
 
Grafos eulerianos y hamiltonianos
Grafos eulerianos y hamiltonianosGrafos eulerianos y hamiltonianos
Grafos eulerianos y hamiltonianosAron Boza
 
Cap5 1.3 tutor3 algoritmos condicionales
Cap5 1.3 tutor3 algoritmos condicionalesCap5 1.3 tutor3 algoritmos condicionales
Cap5 1.3 tutor3 algoritmos condicionalesMary Dunnia Lopez N.
 
2 manipulacion de datos..
2 manipulacion de datos..2 manipulacion de datos..
2 manipulacion de datos..alithu1
 
Expresiones regulares
Expresiones regularesExpresiones regulares
Expresiones regularesJordan-P
 
algoritmos y fundamentos de programacion
algoritmos y fundamentos de programacionalgoritmos y fundamentos de programacion
algoritmos y fundamentos de programacionMIKE_INK_RM
 
Concurrencia interbloqueo e inanición
Concurrencia interbloqueo e inaniciónConcurrencia interbloqueo e inanición
Concurrencia interbloqueo e inaniciónjhonfgarcia
 
Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1Osiris Mirerus
 
Sentencias selectivas y repetitivas
Sentencias selectivas y repetitivasSentencias selectivas y repetitivas
Sentencias selectivas y repetitivasyoly1parra1
 

La actualidad más candente (20)

Teoría de optimización
Teoría de optimizaciónTeoría de optimización
Teoría de optimización
 
Maquina de turing y resolubilidad e Irresolubilidad
Maquina de turing y resolubilidad e IrresolubilidadMaquina de turing y resolubilidad e Irresolubilidad
Maquina de turing y resolubilidad e Irresolubilidad
 
Arquetipos
ArquetiposArquetipos
Arquetipos
 
Divide y Venceras
Divide y VencerasDivide y Venceras
Divide y Venceras
 
Unidad aritmetico logica ALU
Unidad aritmetico logica ALUUnidad aritmetico logica ALU
Unidad aritmetico logica ALU
 
Estructuras de datos lineales
Estructuras de datos linealesEstructuras de datos lineales
Estructuras de datos lineales
 
Algebra relacional
Algebra relacionalAlgebra relacional
Algebra relacional
 
Autómata de Pila
Autómata de Pila Autómata de Pila
Autómata de Pila
 
Máquinas de turing y autómatas acotados
Máquinas de turing y autómatas acotadosMáquinas de turing y autómatas acotados
Máquinas de turing y autómatas acotados
 
Grafos eulerianos y hamiltonianos
Grafos eulerianos y hamiltonianosGrafos eulerianos y hamiltonianos
Grafos eulerianos y hamiltonianos
 
Cap5 1.3 tutor3 algoritmos condicionales
Cap5 1.3 tutor3 algoritmos condicionalesCap5 1.3 tutor3 algoritmos condicionales
Cap5 1.3 tutor3 algoritmos condicionales
 
arreglos y matrices
arreglos  y matricesarreglos  y matrices
arreglos y matrices
 
2 manipulacion de datos..
2 manipulacion de datos..2 manipulacion de datos..
2 manipulacion de datos..
 
Expresiones regulares
Expresiones regularesExpresiones regulares
Expresiones regulares
 
algoritmos y fundamentos de programacion
algoritmos y fundamentos de programacionalgoritmos y fundamentos de programacion
algoritmos y fundamentos de programacion
 
ESTRUCTURA DE UN PROGRAMA
ESTRUCTURA DE UN PROGRAMA ESTRUCTURA DE UN PROGRAMA
ESTRUCTURA DE UN PROGRAMA
 
Concurrencia interbloqueo e inanición
Concurrencia interbloqueo e inaniciónConcurrencia interbloqueo e inanición
Concurrencia interbloqueo e inanición
 
Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1
 
GRAMATICAS AMBIGUAS
GRAMATICAS AMBIGUASGRAMATICAS AMBIGUAS
GRAMATICAS AMBIGUAS
 
Sentencias selectivas y repetitivas
Sentencias selectivas y repetitivasSentencias selectivas y repetitivas
Sentencias selectivas y repetitivas
 

Similar a Capítulo 3 Algoritmos recursivos.pdf

Similar a Capítulo 3 Algoritmos recursivos.pdf (20)

ESTRUCTURA DE DATOS
ESTRUCTURA DE DATOSESTRUCTURA DE DATOS
ESTRUCTURA DE DATOS
 
Recursión
RecursiónRecursión
Recursión
 
Recursividad
RecursividadRecursividad
Recursividad
 
Recursividad
RecursividadRecursividad
Recursividad
 
Recursividad en programación
Recursividad en programaciónRecursividad en programación
Recursividad en programación
 
05 - Funciones en lenguaje C
05 - Funciones en lenguaje C05 - Funciones en lenguaje C
05 - Funciones en lenguaje C
 
Recursividad terminal
Recursividad terminalRecursividad terminal
Recursividad terminal
 
Algoritmos y lenjuage de programacion
Algoritmos y  lenjuage de programacionAlgoritmos y  lenjuage de programacion
Algoritmos y lenjuage de programacion
 
Presentacion
PresentacionPresentacion
Presentacion
 
Funciones
FuncionesFunciones
Funciones
 
Funciones en C
Funciones en CFunciones en C
Funciones en C
 
Funciones
FuncionesFunciones
Funciones
 
Unidad 2 programación estructurada
Unidad 2 programación estructuradaUnidad 2 programación estructurada
Unidad 2 programación estructurada
 
Funcionesclase1
Funcionesclase1Funcionesclase1
Funcionesclase1
 
Script de Punteros a Funciones
Script de Punteros a FuncionesScript de Punteros a Funciones
Script de Punteros a Funciones
 
Algoritmo utilizando pseudolenguaje
Algoritmo utilizando pseudolenguajeAlgoritmo utilizando pseudolenguaje
Algoritmo utilizando pseudolenguaje
 
Funciones
FuncionesFunciones
Funciones
 
8448148681
84481486818448148681
8448148681
 
Funciones en C.docx
Funciones en C.docxFunciones en C.docx
Funciones en C.docx
 
Curso MATLAB
Curso MATLABCurso MATLAB
Curso MATLAB
 

Más de Igor Rodriguez

Presente-Perfecto-Part-3_-just-already-yet-for-since.pptx
Presente-Perfecto-Part-3_-just-already-yet-for-since.pptxPresente-Perfecto-Part-3_-just-already-yet-for-since.pptx
Presente-Perfecto-Part-3_-just-already-yet-for-since.pptxIgor Rodriguez
 
Grupos de trabajos Grupo 1 Proyecto 2 2022.docx
Grupos de trabajos Grupo 1 Proyecto 2  2022.docxGrupos de trabajos Grupo 1 Proyecto 2  2022.docx
Grupos de trabajos Grupo 1 Proyecto 2 2022.docxIgor Rodriguez
 
cuadro_comparativo_SGBD_top_10.docx (1).docx
cuadro_comparativo_SGBD_top_10.docx (1).docxcuadro_comparativo_SGBD_top_10.docx (1).docx
cuadro_comparativo_SGBD_top_10.docx (1).docxIgor Rodriguez
 
Instrucciones-Mesa-Redonda.docx
Instrucciones-Mesa-Redonda.docxInstrucciones-Mesa-Redonda.docx
Instrucciones-Mesa-Redonda.docxIgor Rodriguez
 
Copia de Grupos de trabajos Grupo 3 Proyecto 1 2022.docx
Copia de Grupos de trabajos Grupo 3 Proyecto 1  2022.docxCopia de Grupos de trabajos Grupo 3 Proyecto 1  2022.docx
Copia de Grupos de trabajos Grupo 3 Proyecto 1 2022.docxIgor Rodriguez
 
Ciencias Sociales Docente autoevaluados en Veraguas I y II semestre -.pdf
Ciencias Sociales Docente autoevaluados en Veraguas I y II semestre -.pdfCiencias Sociales Docente autoevaluados en Veraguas I y II semestre -.pdf
Ciencias Sociales Docente autoevaluados en Veraguas I y II semestre -.pdfIgor Rodriguez
 
Lección 4. La Constitución Política de la República de Panamá.docx
Lección 4. La Constitución Política de la República de Panamá.docxLección 4. La Constitución Política de la República de Panamá.docx
Lección 4. La Constitución Política de la República de Panamá.docxIgor Rodriguez
 
Lección 3 Estado, Nación y Gobierno.docx
Lección 3 Estado, Nación y Gobierno.docxLección 3 Estado, Nación y Gobierno.docx
Lección 3 Estado, Nación y Gobierno.docxIgor Rodriguez
 
Lección 1. La Educación Cívica Concepto Definición.docx
Lección 1. La Educación Cívica Concepto Definición.docxLección 1. La Educación Cívica Concepto Definición.docx
Lección 1. La Educación Cívica Concepto Definición.docxIgor Rodriguez
 
Lección 2. La Vida en Sociedad Concepto y Definición.docx
Lección 2. La Vida en Sociedad Concepto y Definición.docxLección 2. La Vida en Sociedad Concepto y Definición.docx
Lección 2. La Vida en Sociedad Concepto y Definición.docxIgor Rodriguez
 
Lección 5. La Educación, Desarrollo Humano y Derechos Humanos.docx
Lección 5. La Educación, Desarrollo Humano y Derechos Humanos.docxLección 5. La Educación, Desarrollo Humano y Derechos Humanos.docx
Lección 5. La Educación, Desarrollo Humano y Derechos Humanos.docxIgor Rodriguez
 
Formato informe final de entrega de modulos del i trimestre y censo del ii tr...
Formato informe final de entrega de modulos del i trimestre y censo del ii tr...Formato informe final de entrega de modulos del i trimestre y censo del ii tr...
Formato informe final de entrega de modulos del i trimestre y censo del ii tr...Igor Rodriguez
 
Verbs transitive and_intransitive
Verbs transitive and_intransitiveVerbs transitive and_intransitive
Verbs transitive and_intransitiveIgor Rodriguez
 

Más de Igor Rodriguez (20)

Presente-Perfecto-Part-3_-just-already-yet-for-since.pptx
Presente-Perfecto-Part-3_-just-already-yet-for-since.pptxPresente-Perfecto-Part-3_-just-already-yet-for-since.pptx
Presente-Perfecto-Part-3_-just-already-yet-for-since.pptx
 
Grupos de trabajos Grupo 1 Proyecto 2 2022.docx
Grupos de trabajos Grupo 1 Proyecto 2  2022.docxGrupos de trabajos Grupo 1 Proyecto 2  2022.docx
Grupos de trabajos Grupo 1 Proyecto 2 2022.docx
 
Documento.docx
Documento.docxDocumento.docx
Documento.docx
 
En blanco.pdf
En blanco.pdfEn blanco.pdf
En blanco.pdf
 
cuadro_comparativo_SGBD_top_10.docx (1).docx
cuadro_comparativo_SGBD_top_10.docx (1).docxcuadro_comparativo_SGBD_top_10.docx (1).docx
cuadro_comparativo_SGBD_top_10.docx (1).docx
 
Instrucciones-Mesa-Redonda.docx
Instrucciones-Mesa-Redonda.docxInstrucciones-Mesa-Redonda.docx
Instrucciones-Mesa-Redonda.docx
 
Copia de Grupos de trabajos Grupo 3 Proyecto 1 2022.docx
Copia de Grupos de trabajos Grupo 3 Proyecto 1  2022.docxCopia de Grupos de trabajos Grupo 3 Proyecto 1  2022.docx
Copia de Grupos de trabajos Grupo 3 Proyecto 1 2022.docx
 
Ciencias Sociales Docente autoevaluados en Veraguas I y II semestre -.pdf
Ciencias Sociales Docente autoevaluados en Veraguas I y II semestre -.pdfCiencias Sociales Docente autoevaluados en Veraguas I y II semestre -.pdf
Ciencias Sociales Docente autoevaluados en Veraguas I y II semestre -.pdf
 
Lección 4. La Constitución Política de la República de Panamá.docx
Lección 4. La Constitución Política de la República de Panamá.docxLección 4. La Constitución Política de la República de Panamá.docx
Lección 4. La Constitución Política de la República de Panamá.docx
 
Lección 3 Estado, Nación y Gobierno.docx
Lección 3 Estado, Nación y Gobierno.docxLección 3 Estado, Nación y Gobierno.docx
Lección 3 Estado, Nación y Gobierno.docx
 
Lección 1. La Educación Cívica Concepto Definición.docx
Lección 1. La Educación Cívica Concepto Definición.docxLección 1. La Educación Cívica Concepto Definición.docx
Lección 1. La Educación Cívica Concepto Definición.docx
 
Lección 2. La Vida en Sociedad Concepto y Definición.docx
Lección 2. La Vida en Sociedad Concepto y Definición.docxLección 2. La Vida en Sociedad Concepto y Definición.docx
Lección 2. La Vida en Sociedad Concepto y Definición.docx
 
Lección 5. La Educación, Desarrollo Humano y Derechos Humanos.docx
Lección 5. La Educación, Desarrollo Humano y Derechos Humanos.docxLección 5. La Educación, Desarrollo Humano y Derechos Humanos.docx
Lección 5. La Educación, Desarrollo Humano y Derechos Humanos.docx
 
TAREA 1.docx
TAREA 1.docxTAREA 1.docx
TAREA 1.docx
 
TAREA 2.docx
TAREA 2.docxTAREA 2.docx
TAREA 2.docx
 
TAREA 4.docx
TAREA 4.docxTAREA 4.docx
TAREA 4.docx
 
TAREA 3.docx
TAREA 3.docxTAREA 3.docx
TAREA 3.docx
 
TAREA 5.docx
TAREA 5.docxTAREA 5.docx
TAREA 5.docx
 
Formato informe final de entrega de modulos del i trimestre y censo del ii tr...
Formato informe final de entrega de modulos del i trimestre y censo del ii tr...Formato informe final de entrega de modulos del i trimestre y censo del ii tr...
Formato informe final de entrega de modulos del i trimestre y censo del ii tr...
 
Verbs transitive and_intransitive
Verbs transitive and_intransitiveVerbs transitive and_intransitive
Verbs transitive and_intransitive
 

Último

EXPANSIÓN ECONÓMICA DE OCCIDENTE LEÓN.pptx
EXPANSIÓN ECONÓMICA DE OCCIDENTE LEÓN.pptxEXPANSIÓN ECONÓMICA DE OCCIDENTE LEÓN.pptx
EXPANSIÓN ECONÓMICA DE OCCIDENTE LEÓN.pptxPryhaSalam
 
Planificacion Anual 4to Grado Educacion Primaria 2024 Ccesa007.pdf
Planificacion Anual 4to Grado Educacion Primaria   2024   Ccesa007.pdfPlanificacion Anual 4to Grado Educacion Primaria   2024   Ccesa007.pdf
Planificacion Anual 4to Grado Educacion Primaria 2024 Ccesa007.pdfDemetrio Ccesa Rayme
 
Identificación de componentes Hardware del PC
Identificación de componentes Hardware del PCIdentificación de componentes Hardware del PC
Identificación de componentes Hardware del PCCesarFernandez937857
 
Planificacion Anual 2do Grado Educacion Primaria 2024 Ccesa007.pdf
Planificacion Anual 2do Grado Educacion Primaria   2024   Ccesa007.pdfPlanificacion Anual 2do Grado Educacion Primaria   2024   Ccesa007.pdf
Planificacion Anual 2do Grado Educacion Primaria 2024 Ccesa007.pdfDemetrio Ccesa Rayme
 
La Función tecnológica del tutor.pptx
La  Función  tecnológica  del tutor.pptxLa  Función  tecnológica  del tutor.pptx
La Función tecnológica del tutor.pptxJunkotantik
 
Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...Lourdes Feria
 
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdfSELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdfAngélica Soledad Vega Ramírez
 
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptxPRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptxinformacionasapespu
 
texto argumentativo, ejemplos y ejercicios prácticos
texto argumentativo, ejemplos y ejercicios prácticostexto argumentativo, ejemplos y ejercicios prácticos
texto argumentativo, ejemplos y ejercicios prácticosisabeltrejoros
 
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...Carlos Muñoz
 
Historia y técnica del collage en el arte
Historia y técnica del collage en el arteHistoria y técnica del collage en el arte
Historia y técnica del collage en el arteRaquel Martín Contreras
 
Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.José Luis Palma
 
DE LAS OLIMPIADAS GRIEGAS A LAS DEL MUNDO MODERNO.ppt
DE LAS OLIMPIADAS GRIEGAS A LAS DEL MUNDO MODERNO.pptDE LAS OLIMPIADAS GRIEGAS A LAS DEL MUNDO MODERNO.ppt
DE LAS OLIMPIADAS GRIEGAS A LAS DEL MUNDO MODERNO.pptELENA GALLARDO PAÚLS
 
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyzel CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyzprofefilete
 
La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.amayarogel
 
programa dia de las madres 10 de mayo para evento
programa dia de las madres 10 de mayo  para eventoprograma dia de las madres 10 de mayo  para evento
programa dia de las madres 10 de mayo para eventoDiegoMtsS
 
MAYO 1 PROYECTO día de la madre el amor más grande
MAYO 1 PROYECTO día de la madre el amor más grandeMAYO 1 PROYECTO día de la madre el amor más grande
MAYO 1 PROYECTO día de la madre el amor más grandeMarjorie Burga
 
TIPOLOGÍA TEXTUAL- EXPOSICIÓN Y ARGUMENTACIÓN.pptx
TIPOLOGÍA TEXTUAL- EXPOSICIÓN Y ARGUMENTACIÓN.pptxTIPOLOGÍA TEXTUAL- EXPOSICIÓN Y ARGUMENTACIÓN.pptx
TIPOLOGÍA TEXTUAL- EXPOSICIÓN Y ARGUMENTACIÓN.pptxlclcarmen
 

Último (20)

Repaso Pruebas CRECE PR 2024. Ciencia General
Repaso Pruebas CRECE PR 2024. Ciencia GeneralRepaso Pruebas CRECE PR 2024. Ciencia General
Repaso Pruebas CRECE PR 2024. Ciencia General
 
EXPANSIÓN ECONÓMICA DE OCCIDENTE LEÓN.pptx
EXPANSIÓN ECONÓMICA DE OCCIDENTE LEÓN.pptxEXPANSIÓN ECONÓMICA DE OCCIDENTE LEÓN.pptx
EXPANSIÓN ECONÓMICA DE OCCIDENTE LEÓN.pptx
 
Planificacion Anual 4to Grado Educacion Primaria 2024 Ccesa007.pdf
Planificacion Anual 4to Grado Educacion Primaria   2024   Ccesa007.pdfPlanificacion Anual 4to Grado Educacion Primaria   2024   Ccesa007.pdf
Planificacion Anual 4to Grado Educacion Primaria 2024 Ccesa007.pdf
 
Identificación de componentes Hardware del PC
Identificación de componentes Hardware del PCIdentificación de componentes Hardware del PC
Identificación de componentes Hardware del PC
 
Planificacion Anual 2do Grado Educacion Primaria 2024 Ccesa007.pdf
Planificacion Anual 2do Grado Educacion Primaria   2024   Ccesa007.pdfPlanificacion Anual 2do Grado Educacion Primaria   2024   Ccesa007.pdf
Planificacion Anual 2do Grado Educacion Primaria 2024 Ccesa007.pdf
 
La Función tecnológica del tutor.pptx
La  Función  tecnológica  del tutor.pptxLa  Función  tecnológica  del tutor.pptx
La Función tecnológica del tutor.pptx
 
Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...
 
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdfSELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
SELECCIÓN DE LA MUESTRA Y MUESTREO EN INVESTIGACIÓN CUALITATIVA.pdf
 
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptxPRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
PRIMER SEMESTRE 2024 ASAMBLEA DEPARTAMENTAL.pptx
 
La Trampa De La Felicidad. Russ-Harris.pdf
La Trampa De La Felicidad. Russ-Harris.pdfLa Trampa De La Felicidad. Russ-Harris.pdf
La Trampa De La Felicidad. Russ-Harris.pdf
 
texto argumentativo, ejemplos y ejercicios prácticos
texto argumentativo, ejemplos y ejercicios prácticostexto argumentativo, ejemplos y ejercicios prácticos
texto argumentativo, ejemplos y ejercicios prácticos
 
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
 
Historia y técnica del collage en el arte
Historia y técnica del collage en el arteHistoria y técnica del collage en el arte
Historia y técnica del collage en el arte
 
Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.
 
DE LAS OLIMPIADAS GRIEGAS A LAS DEL MUNDO MODERNO.ppt
DE LAS OLIMPIADAS GRIEGAS A LAS DEL MUNDO MODERNO.pptDE LAS OLIMPIADAS GRIEGAS A LAS DEL MUNDO MODERNO.ppt
DE LAS OLIMPIADAS GRIEGAS A LAS DEL MUNDO MODERNO.ppt
 
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyzel CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
 
La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.
 
programa dia de las madres 10 de mayo para evento
programa dia de las madres 10 de mayo  para eventoprograma dia de las madres 10 de mayo  para evento
programa dia de las madres 10 de mayo para evento
 
MAYO 1 PROYECTO día de la madre el amor más grande
MAYO 1 PROYECTO día de la madre el amor más grandeMAYO 1 PROYECTO día de la madre el amor más grande
MAYO 1 PROYECTO día de la madre el amor más grande
 
TIPOLOGÍA TEXTUAL- EXPOSICIÓN Y ARGUMENTACIÓN.pptx
TIPOLOGÍA TEXTUAL- EXPOSICIÓN Y ARGUMENTACIÓN.pptxTIPOLOGÍA TEXTUAL- EXPOSICIÓN Y ARGUMENTACIÓN.pptx
TIPOLOGÍA TEXTUAL- EXPOSICIÓN Y ARGUMENTACIÓN.pptx
 

Capítulo 3 Algoritmos recursivos.pdf

  • 1. Diseño de estructuras de datos y algoritmos 1 Capítulo 3 Algoritmos recursivos Los algoritmos recursivos se basan en la metodología de llamar repetidamente la propia función en que están definidos, y son de gran utilidad en multitud de campos en la informática. Al finalizar el estudio de estas lecciones serás capaz de: Conocer los fundamentos y características de los algoritmos recursivos. Conocer el funcionamiento de las funciones recursivas. Conocer las características fundamentales de las estructuras de datos recursivas. Conocer las ventajas y desventajas de las funciones recursivas frente a las funciones iterativas.
  • 2. Diseño de estructuras de datos y algoritmos 2 Lección 1 Algoritmos recursivos Introducción Una técnica común de resolución de problemas es la división de un problema en varios subproblemas de la misma categoría, pero de más fácil resolución. Esta técnica se conoce como divide y vencerás. Un ejemplo de algoritmos en los que se aplica esta técnica son los algoritmos recursivos, en los cuales el algoritmo se llama a sí mismo repetidamente, procurando simplificar o reducir el problema en cada llamada, hasta llegar a un caso trivial de solución directa. La mayoría de los lenguajes soportan los algoritmos recursivos, permitiendo que una función se llame a sí misma. En un algoritmo recursivo, los bucles típicos de un algoritmo iterativo (para..hasta, mientras…) se sustituyen por llamadas al propio algoritmo. Al escribir un algoritmo recursivo, debe establecerse de algún modo cuando debe dejar de llamarse a sí mismo, o de otra forma se repetiría indefinidamente. Para ello, se establece una condición de salida llamada caso base. La recursividad es una técnica de programación que busca resolver un problema sustituyéndolo por otros problemas de la misma categoría, pero más simples. Se dice que un algoritmo es recursivo si dentro del cuerpo del algoritmo y de forma directa o indirecta se realiza una llamada a él mismo.
  • 3. Diseño de estructuras de datos y algoritmos 3 El caso base contempla el caso en el cual la solución es lo suficientemente sencilla como para responder directamente sin necesidad de realizar otra llamada al algoritmo. El ejemplo más típico de algoritmo recursivo es el de una función para calcular el factorial de un número. El factorial de un número es el resultado de multiplicar dicho número por todos los precedentes, hasta llegar a 1. Por ejemplo, factorial(3) = 3 * 2 * 1. Si observamos que el factorial de un número es equivalente al producto de dicho número por el factorial del número precedente: factorial(3) = 3 * factorial(2) podemos plantear una implementación recursiva: función factorial(n) si n = 1 devolver 1 sino devolver n * factorial(n – 1) fin si fin función En este caso, la sentencia si n = 1 devolver 1 es la condición de salida o caso base que evita que la función se llame a sí misma indefinidamente. Todo algoritmo recursivo debe incluir al menos un caso base y garantizar que se ejecuta en algún momento para evitar la recursividad infinita. Se llama caso base o condición de salida al caso trivial de un algoritmo recursivo, del cual conocemos su solución.
  • 4. Diseño de estructuras de datos y algoritmos 4 El concepto de recursividad pone una gran potencia al alcance del programador y adquiere una dimensión fundamental en los llamados lenguajes de programación funcionales, los cuales a menudo no incorporan sentencias que permitan crear bucles, debiendo recurrir a las llamadas recursivas para implementar repeticiones. Se pueden establecer diferentes categorías de recursividad en virtud de la característica del algoritmo analizada: ▪ Según el punto desde el cual se hace la llamada recursiva: recursividad directa o indirecta. ▪ Según el número de llamadas recursivas efectuadas en tiempo de ejecución: recursividad lineal o no lineal. ▪ Según el punto del algoritmo desde donde se efectúa la llamada recursiva: recursividad final o no final. Para obtener más información respecto a los lenguajes de programación funcionales, consulta la dirección Web http://es.wikipedia.org/wiki/Programaci%C3%B3n_funcional La mayoría de los algoritmos que pueden ser descritos de forma iterativa (es decir, haciendo uso de bucles while, for…) pueden ser reescritos de forma recursiva, y viceversa. Al hablar de funciones recursivas, nos referimos a algoritmos recursivos implementados en un lenguaje particular. Aunque hemos elegido el término genérico función, pueden emplearse otros similares como procedimiento o método.
  • 5. Diseño de estructuras de datos y algoritmos 5 Recursividad directa y recursividad indirecta ▪ Recursividad directa: Se da cuando la función efectúa una llamada a sí misma. ▪ Recursividad indirecta: Se da cuando una función A llama a otra función B la cual a su vez, y de forma directa o indirecta, llama nuevamente a A. Recursividad lineal y recursividad no lineal ▪ Recursividad lineal o simple: Se da cuando la recursividad es directa y además cada llamada a la función recursiva sólo hace una nueva llamada recursiva. ▪ Recursividad no lineal o múltiple: La ejecución de una llamada recursiva da lugar a más de una llamada a la función recursiva. función A … si condición A(…) fin si … A(…) … fin función La recursividad será no lineal si se cumple condición, pues en tal caso se producen dos llamadas recursivas. función A … A(…) … fin función función A … A(…) … fin función función A … B(…) … fin función función B … A(…) … fin función
  • 6. Diseño de estructuras de datos y algoritmos 6 Recursividad final y recursividad no final ▪ Recursividad final: Se da cuando la llamada recursiva es la última operación efectuada en el cuerpo de la función. (sin tener en cuenta la sentencia devolver) ▪ Recursividad no final: Se da cuando la llamada recursiva no es la última operación realizada dentro de la función (sin tener en cuenta la sentencia devolver) función A … devolver A(…) + 5 fin función La llamada a la función recursiva no es la última operación efectuada (en ambos casos es una suma) función A … devolver A(…) + A(…) fin función función A … devolver A(…) fin función No existe ningún procesamiento posterior a la llamada a A(). Explicaremos más a fondo la recursividad final en la Lección 4 – Funciones recursivas finales. La secuencia de Fibonacci, definida por la fórmula fib(n) = n si n = 0 o si n = 1 fib(n) = fib(n – 2) + fib(n – 1) si n >= 2 es un ejemplo de recursividad múltiple y no final. Para el caso n>=2 se producen dos llamadas recursivas, y al regresar de la llamada recursiva el resultado no se devuelve tal cual sino que se suma con el resultado de otra llamada recursiva.
  • 7. Diseño de estructuras de datos y algoritmos 7 Diseño de funciones recursivas Para escribir un algoritmo de forma recursiva es necesario intentar transformar el problema en otro similar pero más simple, así como encontrar una solución directa para los casos triviales. Es necesario, pues: ▪ Identificar y formular el caso base o condición de salida del cual conocemos la solución directamente. ▪ Formular el caso general que debe poder resolverse en función del caso base y una transformación del caso general hacia uno más sencillo.
  • 8. Diseño de estructuras de datos y algoritmos 8 Lección 2 Mecanismo de recursividad La pila de llamadas Para comprender el funcionamiento de un algoritmo recursivo es fundamental conocer como funciona la pila de llamadas de un programa en ejecución. Todo programa en ejecución tiene una pila asociada para éste propósito. En los lenguajes de alto nivel (como C o Java) la gestión de la pila de llamadas la realiza de forma automática el compilador, y el programador no necesita preocuparse de su funcionamiento. Cuando en un punto concreto de un programa se llama a una función -sea recursiva o no- se reserva espacio en la pila para la siguiente información: ▪ La dirección de retorno de la función: De modo que sea posible regresar al punto de ejecución inmediatamente posterior al de la llamada a la función. ▪ Los parámetros de la llamada: La función llamada obtiene los parámetros (también llamados argumentos) de la pila. Por ejemplo, en una función para sumar dos números, los argumentos serían los números a sumar. ▪ Espacio para las variables locales El compilador reserva espacio en la pila para almacenar las variables locales. La cantidad de espacio reservado es proporcional al número de variables locales definidas y al tamaño requerido por cada variable (carácter, entero, real…). ▪ El resultado devuelto por la función Opcionalmente, ya que también es posible y usual devolver el resultado de la llama a la función en uno de los registros de la CPU. Dependiendo del lenguaje de programación y arquitectura de ejecución elegidos, suelen asignarse funciones extra a la pila de llamadas (por ejemplo, en los lenguajes orientados a objetos a menudo también se almacena en la pila el puntero al objeto cuyo método estamos llamando, “this”). La pila de llamadas (call stack en inglés) es un segmento de memoria basado en una estructura de datos del tipo pila utilizada para almacenar información relacionada con las llamadas a funciones dentro de un programa.
  • 9. Diseño de estructuras de datos y algoritmos 9 En el siguiente esquema se ejemplifica la ejecución de la función main() de un programa. La columna dirección de memoria contiene la dirección de memoria (hipotética) asignada a las diferentes sentencias del programa. Conforme una función llama a otra, se almacenan los datos correspondientes en la pila: Una vez una función regresa después de su ejecución, se descarta de forma automática el espacio en la pila que se le había asignado. De esta forma, la pila va creciendo y decreciendo. Cuanto mayor es el nivel de anidamiento de llamadas a funciones, mayor es el espacio de memoria ocupado en la pila, y existe incluso la posibilidad de ocupar todo el espacio de memoria que tiene asignado. Este hecho se conoce como desbordamiento de pila (stack overflow en inglés). Por esta razón es muy importante evitar que una función recursiva se llame indefinidamente: no sólo el programa se quedaría “colgado”, sino que saturaríamos por completo la memoria destinada a la pila. función main() … funciónA(5) … fin función 5 Pila … 23 24 parámetro 5 dirección de memoria … función A() … funciónB(8,9) … fin función 60 … 67 68 80 … 24 8 9 68 Llamada a funciónB dirección de crecimiento de la pila dir. retorno Espacio variables Llamada a funciónA función B() … fin función
  • 10. Diseño de estructuras de datos y algoritmos 10 Llamadas recursivas Una vez visto el funcionamiento básico de la pila de llamadas de un programa, podemos estudiar el uso de la pila en una función recursiva con un ejemplo. Para ello, seguiremos con el ejemplo del cálculo del factorial de un número. El siguiente esquema muestra el uso de la pila que resulta de hacer una llamada a la función factorial: En cada llamada recursiva, se requiere espacio en la pila para almacenar dirección de retorno, parámetros y resultado de la llamada. La pila crece hacia arriba conforme se efectúan las llamadas: llamada principal, 1ª llamada recursiva, 2ª llamada recursiva y 3ª llamada recursiva (la final, que llega al caso base). En el esquema anterior se han introducido en la pila los valores finales devueltos por las llamadas recursivas, pero el espacio asignado en la pila para el resultado de la llamada contiene un valor sin definir inicialmente. La dirección de retorno es la misma en todos los casos, ya que la instrucción siguiente a cada una de las llamadas es idéntica en todos los casos. 24 función factorial(n) … factorial(n - 1) … fin función 2 … 23 24 parámetro n Llamada inicial: factorial(3) … 2 24 1 1 24 2ª llamada dir. retorno resultado 1ª llamada 6 Llamada principal 3 0 1 24 3ª llamada
  • 11. Diseño de estructuras de datos y algoritmos 11 Conforme las llamadas devuelven su resultado, se libera el espacio asignado en la pila para dicha llamada: De este modo, tras la llamada factorial(3) la pila se encuentra de nuevo en el estado en el que se encontraba justo antes de la llamada a la función. datos llamada principal PILA Paso 1 datos llamada principal PILA Paso 2 datos 1ª llamada recursiva datos llamada principal PILA Paso 3 datos 1ª llamada recursiva datos 2ª llamada recursiva datos llamada principal PILA Paso 4 datos 1ª llamada recursiva datos 2ª llamada recursiva datos 3ª llamada recursiva datos llamada principal PILA Paso 5 datos 1ª llamada recursiva datos 2ª llamada recursiva 3ª llamada devuelve 1 datos llamada principal PILA Paso 6 datos 1ª llamada recursiva 2ª llamada devuelve 1 datos llamada principal PILA Paso 7 1ª llamada devuelve 2 PILA Paso 8 llamada ppal. devuelve 6 1 Escribe un algoritmo recursivo que calcule el elemento de cardinal más elevado de un vector de datos de tipo entero. Por ejemplo, para la entrada {1, 3, 25, 9, 20} obtendremos como resultado 25.
  • 12. Diseño de estructuras de datos y algoritmos 12 2 El valor de xn se puede definir recursivamente como: x0 = 1 xn = x * xn – 1 Implementa de forma recursivo el cálculo de xn para cualquier valor de X y n.
  • 13. Diseño de estructuras de datos y algoritmos 13 Lección 3 Estructuras de datos recursivas Introducción A menudo encontramos problemas cuya información puede presentarse de forma natural como una estructura de datos de tipo lista, pila, cola, árbol o grafo. Dado que dichas estructuras de datos poseen en sí mismas carácter recursivo (pues se incluyen a si mismas en su definición), resulta natural tratar estos problemas con algoritmos recursivos. Vamos a estudiar brevemente la aplicación del concepto de recursividad a listas enlazadas y árboles. La extensión a otros tipos de estructuras de datos es sencilla debido a su similitud (todas ellas incluyen referencias al siguiente o siguientes elementos). Listas enlazadas En una estructura del tipo lista enlazada cada nodo contiene una referencia al siguiente nodo (alternativamente es posible que contenga una referencia al nodo anterior, en las listas doblemente encadenadas), y un conjunto de atributos extra específicos del nodo en cuestión: Una función que opere de forma recursiva sobre una lista enlazada, deberá procesar el nodo actual y pasar como parámetro el nodo siguiente. La condición de salida en este caso se dará cuando lleguemos a un nodo de valor null, que indicará el final de la lista: Árboles En una estructura del tipo árbol cada nodo contiene una referencia a los hijos izquierdo y derecho de la rama actual: función procesaLista(nodo) si nodo <> null imprime(nodo.dato) procesaLista(nodo.siguiente) fin si fin función estructura Nodo dato: entero siguiente: Nodo fin estructura
  • 14. Diseño de estructuras de datos y algoritmos 14 El algoritmo se llama pasando como parámetro inicial el nodo raíz del árbol, y las llamadas siguientes procesan los nodos hijos o subárboles del nodo principal, hasta llegar al caso base, que en un árbol corresponde a un nodo que no tiene nodos hijos, es decir, un nodo cuyos atributos hijoIzq e hijoDch son null. Estos nodos reciben el nombre de hojas del árbol. En el caso de un árbol, se procesan recursivamente tanto su lado izquierdo como su lado derecho: función procesaArbol(nodo) si nodo <> null imprime(nodo.dato) procesaArbol(nodo.hijoIzq) procesaArbol(nodo.hijoIzq) fin si fin función estructura Nodo dato : entero hijoIzq, hijoDch: Nodo fin estructura
  • 15. Diseño de estructuras de datos y algoritmos 15 Lección 4 Funciones recursivas finales Funciones recursivas finales En ocasiones se descarta el uso de funciones recursivas por el uso adicional de memoria que a menudo requieren respecto a la versión iterativa del mismo algoritmo. Cada llamada requiere espacio de pila para la dirección de retorno, parámetros pasados, etc. No obstante, existe un tipo de funciones recursivas, llamadas funciones recursivas finales, en las cuales el tamaño de memoria de la pila utilizado no se ve afectado por el nivel de profundidad de recursión alcanzado. Para que una función recursiva sea final de pleno derecho, la llamada recursiva a la función debe ser la última operación realizada: Ejemplos___________________________________________________________ De las siguientes funciones recursivas, solo la última, recursiva3, es recursiva final; en el resto se efectúan otras operaciones después de la llamada a la función: función recursivaA() num := 10 recursivaA(); a = a + 4; devolver num fin función función recursivaB() int q = 4; q = q + 5; devolver q + test1() fin función función recursiva3 () int b = 5; b = b + 2; devolver recursiva3() Se llama función recursiva final (tail-call recursive function en inglés) a toda función recursiva cuya última operación es la llamada recursiva en sí.
  • 16. Diseño de estructuras de datos y algoritmos 16 fin función __________________________________________________________________ Tras realizar la llamada recursiva la función ya no necesita del espacio en la pila, puesto que: - no va a hacer más uso de los parámetros pasados por la función llamante y guardados en la pila - no va a hacer más uso de variables locales - no va a procesar el valor de retorno Por tanto, el compilador puede incluir código que de forma automática reutilice el espacio en pila reservado para la llamada a la función, de modo que sea utilizado por la siguiente llamada. De este modo, la penalización en tiempo que supone inicializar la pila para la siguiente llamada recursiva desaparece: Simplemente es necesario escribir los nuevos valores de los parámetros sobre los antiguos: Con esta optimización, la eficiencia de una función recursiva se pone a la par de la versión iterativa del mismo algoritmo. 24 función rec(n) … rec(n - 1) fin función … 23 24 parámetro n Llamada inicial: rec(3) … dir. retorno resultado El parámetro se reescribe en cada llamada 5 Pila No todos los compiladores soportan la optimización de funciones recursivas finales.
  • 17. Diseño de estructuras de datos y algoritmos 17 Lección 5 Recursividad vs. iteración Recursividad vs Iteración La mayoría de los algoritmos pueden expresarse tanto de forma iterativa como de forma recursiva. A la hora de implementar un algoritmo, surge la duda respecto a la conveniencia de utilizar una versión u otra. A menudo los programadores acostumbrados al uso de lenguajes imperativos como C o Java descartan el uso de funciones recursivas, aludiendo a razones de eficiencia o memoria. Sin embargo, dichas deficiencias pueden minimarse a menudo. Existen distintos factores a considerar; a continuación enumeramos los más importantes: ▪ Conveniencia - por el lenguaje de programación utilizado Algunos lenguajes se benefician del uso de funciones recursivas respecto a las funciones iterativas. Por ejemplo, los llamados lenguajes funcionales, como Lisp, Scheme o Haskell, están orientados y optimizados para el trabajo con funciones recursivas. - por la definición del problema Hay problemas cuya definición y/o solución son inherentemente recursivas y una solución iterativa resultaría demasiado complicada. Lo contrario también es posible. ▪ Eficiencia En general la versión iterativa de una función siempre es más eficiente que la versión recursiva, tanto en términos de velocidad de ejecución como de memoria utilizada: - Velocidad de ejecución: En la versión recursiva, el hecho de que la función se llame a sí misma incurre en tiempo extra de proceso: La llamada a una función supone un coste extra en términos de tiempo de procesador en comparación con el coste que supone reiniciar una nueva iteración de un bucle: es necesario almacenar los parámetros pasados (si los hay) en la pila, así como la dirección de retorno, etc.
  • 18. Diseño de estructuras de datos y algoritmos 18 No obstante, si el compilador soporta las funciones recursivas finales y podemos escribir el algoritmo como tal, la eficiencia se pone a la par de la versión iterativa. - Uso de memoria: En la versión recursiva, la llamada a la función requiere del uso de la pila para almacenar los parámetros pasados (si los hay), dirección de retorno, resultado, etc. Si el nivel de recursión puede ser muy elevado, el uso de memoria puede ser considerable o incluso prohibitivo. No obstante, algunos algoritmos, en su versión iterativa, requieren de estructuras de datos auxiliares que son implícitas a la versión recursiva del algoritmo al pasar los datos como parámetros en la pila, de modo que consumen también mucha memoria, al nivel de la versión recursiva. ▪ Sencillez En ocasiones es mucho más sencillo escribir la versión recursiva de un algoritmo que la versión iterativa, y viceversa. La elección de una u otra alternativa puede basarse en este hecho. En general, la versión recursiva de una función es mucho más elegante y sencilla a nivel de cantidad de código requerido que la versión iterativa. ▪ Intuitividad El planteamiento iterativo de una función resulta a menudo más intuitivo que el recursivo, y viceversa. Es posible favorecer la legibilidad y comprensibilidad del código respecto a la eficiencia si ésta no es un factor determinante. De forma general, si la eficiencia es un factor importante y/o el algoritmo se va a ejecutar de forma frecuente, conviene escribir una solución iterativa. 1 Reescribe el algoritmo para calcular el factorial de un número de forma iterativa.