You are on page 1of 23

BACHILLER INDUSTRIAL Y PERITO EN COMPUTACION ESTRUCTURA DE DATOS PROF.

ALVARO MARTINEZ

DELMAR ABISAI HERRERA HERRERA SEXTO GRADO 16 DE AGOSTO DE 2013

Recursin

INTRODUCCION: Recursin es, en ciencias de computacin, una forma de atajar y solventar problemas. De hecho, recursin es una de las ideas centrales de ciencia de computacin. Resolver un problema mediante recursin significa que la solucin depende de las soluciones de pequeas instancias del mismo problema. A continuacin se presenta el desarrollo del tema con relacin a estructura de datos.

Recursin
Contenido
RECURSION ............................................................................................................................................................ 4 Algoritmos recursivos: ....................................................................................................................................... 4 Programacin Recursiva:................................................................................................................................... 5 Ejemplos de subrutinas definidas recursivamente (recursin generativa)..................................... 6 Factorial ................................................................................................................................................................... 6 Fibonacci ................................................................................................................................................................. 8 Mximo comn divisor ...................................................................................................................................... 9 Torres de Hani .................................................................................................................................................. 11 Bsqueda binaria ............................................................................................................................................... 13 Estructuras de datos recursivos (recursin estructural) ...................................................................... 16 Listas enlazadas .................................................................................................................................................. 16 rboles binarios ................................................................................................................................................. 17 Recursin frente a iteracin ........................................................................................................................... 18 Funciones de recursin de cola .................................................................................................................... 19 Recursin directa e indirecta ......................................................................................................................... 20

Recursin
RECURSION
Recursin es, en ciencias de computacin, una forma de atajar y solventar problemas. De hecho, recursin es una de las ideas centrales de ciencia de computacin. Resolver un problema mediante recursin significa que la solucin depende de las soluciones de pequeas instancias del mismo problema. El poder de la recursin evidentemente se fundamenta en la posibilidad de definir un conjunto infinito de objetos con una declaracin finita. Igualmente, un nmero infinito de operaciones computacionales puede describirse con un programa recursivo finito, incluso en el caso de que este programa no contiene repeticiones explcitas." La mayora de los lenguajes de programacin dan soporte a la recursin permitiendo a una funcin llamarse a s misma desde el texto del programa. Los lenguajes imperativos definen las estructuras de loops como while y for que son usadas para realizar tareas repetitivas. Algunos lenguajes de programacin funcionales no definen estructuras de loops sino que posibilitan la recursin llamando cdigo de forma repetitiva. La teora de la computabilidad ha demostrado que estos dos tipos de lenguajes son matemticamente equivalentes, es decir que pueden resolver los mismos tipos de problemas, aunque los lenguajes funcionales carezcan de las tpicas estructuras while y for.

Algoritmos recursivos:
Un mtodo frecuente para simplificar es dividir un problema en problemas ms derivados de menor tamao del mismo tipo. Esto se conoce como dialecting. Cmo tcnica de programacin se denomina divide y vencers y es pieza fundamental para el diseo de muchos algoritmos de importancia, as como parte esencial de la programacin dinmica. Virtualmente todos los lenguajes de programacin modernos permiten la especificacin directa de funciones y subrutinas recursivas. Cuando se llama una funcin de este tipo, el ordenador (para la mayora de lenguajes en casi todas las arquitecturas basadas en unapila (stack) o la implementacin en el lenguaje llevan la cuenta de las distintas instancias de la funcin (en numerosas arquitecturas mediante el uso de un call stack,

Recursin
aunque no de forma exclusiva). A la inversa, toda funcin recursiva puede transformarse en una funcin iterativa usando un stack. La mayora (aunque no todas) las funciones y subrutinas que pueden ser evaluadas por un ordenador, pueden expresarse en trminos de una funcin recursiva (sin tener que utilizar una iteracin pura); a la inversa, cualquier funcin recursiva puede expresarse en trminos de una iteracin pura, dado que la recursin es, de por s, tambin iterativa. Para evaluar una funcin por medio de la recursin, tiene que definirse como una funcin de si misma (ej. el factor n! = n * (n - 1)! , donde 0! se define como 1). Resulta evidente que no todas las evaluaciones de funciones se prestan a un acercamiento recursivo. Por lo general, todas las funciones finitas pueden describirse directamente de forma recursiva; las funciones infinitas (ej. las series de e = 1/1! + 2/2! + 3/3!...) necesitan un criterio extra para detenerse, ej. el nmero de iteraciones, o el nmero de dgitos significativos, en caso contrario una iteracin recursiva resultara en un bucle infinito. A modo de ilustracin: Si se encuentra una palabra desconocida en un libro, el lector puede anotar la pgina actual en un papel y ponerlo en una pila (hasta entonces vaca). El lector consulta la palabra en otro artculo y, de nuevo, descubre otra palabra desconocida, la anota y la pone en la pila, y as sucesivamente. Llega un momento que el lector lee un artculo que donde todas las palabras son conocidas. El lector retorna entonces a la ltima pgina y continua la lectura desde ah, y as hasta que se retira la ltima nota de la pila retornando entonces al libro original. Este modus operandi es recursivo. Algunos lenguajes diseados para programacin lgica y programacin funcional ofrecen la recursin como el nico medio de repeticin directa disponible para el programador. Estos lenguajes suelen conseguir que la recursin de cola sea tan eficiente como la iteracin, permitiendo a los programadores expresar otras estructuras repetitivas (tales como map y for de scheme) en trminos de recursin. La recursin est profundamente anclada en la teora de computacin, con la equivalencia terica de funcin micro recursiva y mquinas de Turing en la cimentacin de ideas sobre la universalidad del ordenador moderno.

Programacin Recursiva:
Crear una subrutina recursiva requiere principalmente la definicin de un "caso base", y entonces definir reglas para subdividir casos ms complejos en el caso base. Para una subrutina recursiva es esencial que con cada llamada recursiva, el problema se reduzca de forma que al final llegue al caso base.

Recursin
Algunos expertos clasifican la recursin como "generativa" o bien "estructural". La distincin se hace segn de donde provengan los datos con los que trabaja la subrutina. Si los datos proceden de una estructura de datos similar a una lista, entonces la subrutina es "estructuralmente recursiva"; en caso contrario, es "generativamente recursiva". Muchos algoritmos populares generan una nueva cantidad de datos a partir de los datos aportados y recurren a partir de ah. HTDP (How To Design Programs), al espaol, "Cmo disear programas", se refiere a esta variante como recursin generativa. Ejemplos de recursin generativa incluyen: mximo comn divisor, quicksort, bsqueda binaria, mergesort, Mtodo de Newton, fractals e integracin adaptiva.

Ejemplos de subrutinas definidas recursivamente (recursin generativa) Factorial


Un ejemplo clsico de una subrutina recursiva es la funcin usada para calcular el factorial de un entero. Definicin de la funcin:

Pseudocdigo (recursivo): funcin input: entero n de forma que n output: [n (n-1) (n-2) 1] factorial: >= 0

1. if n es 0, return 1 2. else, return [ n factorial(n-1) ]

end factorial

Recursin
Una relacin recurrente es una ecuacin que relaciona trminos posteriores en la secuencia con trminos previos. Relacin recurrente de un factorial:

Computando la relacin recurrente para n = 4: b4 = 4 * 3 * b2 = 4 * 3 * 2 * b1 = 4 * 3 * 2 * 1 * b0 =4*3*2*1*1 =4*3*2*1 =4*3*2 =4*6 = 24 = 4 * b3

Esta funcin factorial tambin puede describirse sin usar recursin hacienda uso de tpicas estructuras de bucle que se encuentran en lenguajes de programacin imperativos: Pseudocdigo (iterativo): funcin input: entero n de factorial forma que n >= es: 0

output: [n (n-1) (n-2) 1]

1. crear una variable nueva llamada running_total con un valor = 1

Recursin
2. begin loop 1. si n es = 0, salir del loop 2. cambiar running_total a (running_total n) 3. decrementar n 4. repetir el loop

3. return running_total

end factorial El lenguaje de programacin scheme es, sin embargo, un lenguaje de programacin funcional y no define estructuras de loops de cualquier tipo. Se basa nicamente en la recursin para ejecutar todo tipo de loops. Dado que scheme es recursivo de cola, se puede definir una subrutina recursiva que implementa la subrutina factorial como un proceso iterativo, es decir, usa espacio constante pero tiempo lineal.

Fibonacci
Otra popular secuencia recursiva es el Nmero de Fibonacci. Los primeros elementos de la secuencia son: 0, 1, 1, 2, 3, 5, 8, 13, 21... Definicin de la funcin:

Pseudocdigo function fib is: input: entero n de forma que n >= 0

Recursin
1. si n es = 0, return 0 2. si n es = 1, return 1 3. else, return [ fib(n-1) + fib(n-2) ]

end fib Relacin bn = b1 = 1, b0 = 0 Computando la relacin recurrente para n = 4: b4 = b3 + b2 = b2 + b1 + b1 + b0 = b1 + b0 + 1 + 1 + 0 =1+0+1+1+0 =3 Este algoritmo de Fibonacci es especialmente malo pues cada vez que se ejecuta la funcin, realizar dos llamadas a la funcin a s misma, cada una de las cuales har a la vez dos llamadas ms y as sucesivamente hasta que terminen en 0 o en 1. El ejemplo se denomina "recursin de rbol", y sus requisitos de tiempo crecen de forma exponencial y los de espacio de forma lineal.7 recurrente para bn-1 + Fibonacci: bn-2

Mximo comn divisor


Otro famosa funcin recursiva es el algoritmo de Euclides, usado para computar el mximo comn divisor de dos enteros. Definicin de la funcin:

Recursin
Pseudocdigo (recursivo): function gcd is: input: entero x, entero y de forma que x >= y y y > 0

1. if y is 0, return x 2. else, return [ gcd( y, (remainder of x/y) ) ]

end gcd Relacin recursiva del mximo comn denominador, donde divisin entera : expresa el resto de la

Computando la relacin recurrente para x = 27 e y = 9: gcd(27, 9) = gcd(9, 27 % 9) = gcd(9, 0) =9 Computando la relacin recurrente para x = 259 e y = 111: gcd(259, 111) = gcd(111, 259 % 111) = gcd(111, 37) = gcd(37, 0) = 37 Ntese que el algoritmo "recursivo" mostrado arriba es, de hecho, nicamente de cola recursiva, lo que significa que es equivalente a un algoritmo iterativo. En el ejemplo siguiente se muestra el mismo algoritmo usando explcitamente iteracin. No acumula una

10

Recursin
cadena de operaciones deferred, sino que su estado es, ms bien, mantenido completamente en las variables x e y. Su "number of steps grows the as the logarithm of the numbers involved. ",8 al espaol "nmero de pasos crece a medida que lo hace el logaritmo de los nmeros involucrados." Pseudocdigo: funcin gcd es:

input: entero x, entero y de forma que x >= y e y > 0

1. crear una nueva variable llamada remainder

2. begin loop 1. if y is zero, exit loop 2. set remainder to the remainder of x/y 3. set x to y 4. set y to remainder 5. repeat loop

3. return x

end gcd El algoritmo iterativo requiere una variable temporal, e incluso supuesto el conocimiento del Algoritmo de Euclides es ms difcil de entender el proceso a simple vista, aunque los dos algoritmos son muy similares en sus pasos.

Torres de Hani
El problema, puesto de forma simple, es el siguiente: Dadas 3 pilas, una con un conjunto de N discos de tamao creciente, determina el mnimo (ptimo) nmero de pasos que

11

Recursin
lleva mover todos los discos desde su posicin inicial a otra pila sin colocar un disco de mayor tamao sobre uno de menor tamao. Definicin de la funcin:

Relacin de recurrencia para hanoi:

Computacin de la relacin de recurrencia para n = 4: hanoi(4) = 2*hanoi(3) + 1

= 2*(2*hanoi(2) + 1) + 1 = 2*(2*(2*hanoi(1) + 1) + 1) + 1 = 2*(2*(2*1 + 1) + 1) + 1 = 2*(2*(3) + 1) + 1 = 2*(7) + 1 = 15

Ejemplos de implementacin: Pseudocdigo (recursivo): function input: integer n, such that n >= 1 hanoi is:

1. if n is 1 then return 1

2. return [2 * [call hanoi(n-1)] + 1]

12

Recursin
end hanoi

Aunque no todas las funciones recursivas tienen una solucin explcita, la secuencia de la Torre de Hanoi puede reducirse a una frmula explcita. Una formula explcita de las Torres de Hanoi: h1 = 1 = 21 - 1 h2 = 3 = 22 - 1 h3 = 7 = 23 - 1 h4 = 15 = 24 - 1 h5 = 31 = 25 - 1 h6 = 63 = 26 - 1 h7 = 127 = 27 - 1 Por lo general: hn = 2n - 1, for all n >= 1

Bsqueda binaria
El algoritmo de bsqueda binaria es un mtodo de bsqueda de un dato en un vector de datos ordenado dividiendo el vector en dos tras cada pasada. El truco es escoger un punto cerca del centro del vector, comparar en ese punto el dato con el dato buscado para responder entonces a una de las siguientes 3 condiciones: se encuentra el dato buscado, el dato en el punto medio es mayor que el valor buscado o el dato en el punto medio es menor que el valor buscado. Se usa recursin en este algoritmo porque tras cada pasada se crea un nuevo vector dividiendo en orginal en dos. La subrutina de bsqueda binaria se llama entonces de forma recursiva, cada vez con un vector de menor tamao. El tamao del vector se ajusta normalmente cambiando el ndice inicial y final. El algoritmo muestra un

13

Recursin
orden logaritmo de crecimiento porque divide esencialmente el dominio del problema en dos tras cada pasada. Ejemplo de implementacin de la bsqueda binaria: /* Call binary_search with proper initial conditions.

Entrada: Los datos se presentan en forma de vector de [[nmero entero|nmeros enteros]] ordenado de forma ascendente, ''toFind'' es el nmero entero a buscar, ''count'' es el nmero total de elementos del vector

Salida: resultado de la bsqueda binaria

*/ int search(int *data, int toFind, int count) { // Start = 0 (ndice inicial) // End = count - 1 (ndice superior) return binary_search(data, toFind, 0, count-1); }

/* Algoritmo de la bsqueda binaria.

14

Recursin

Entrada: Los datos se presentan en forma de vector de [[nmero entero|nmeros enteros]] ordenado de forma ascendente, ''toFind'' es el nmero entero a buscar, ''start'' es el ndice mnimo del vector, ''end'' es el ndice mximo del vector Salida: posicin del nmero entero ''toFind'' dentro del vector de datos, -1 en caso de bsqueda fallida */ int binary_search(int *data, int toFind, int start, int end) { //Averigua el punto medio. int mid = start + (end - start)/2; //Divisin de enteros

//Condicin para detenerse. if (start > end) return -1; else if (data[mid] == toFind) return mid; else if (data[mid] > toFind) inferior return binary_search(data, toFind, start, mid-1); else //El dato es menor que ''toFind'', se busca en la mitad superior //El dato es mayor que ''toFind'', se busca en la mitad //Encontrado?

15

Recursin
return binary_search(data, toFind, mid+1, end); }

Estructuras de datos recursivos (recursin estructural)


Una aplicacin de importancia de la recursin en ciencias de la computacin es la definicin de estructuras de datos dinmicos tales como listas y rboles. Las estructuras de datos recursivos pueden crecer de forma dinmica hasta un tamao terico infinito en respuesta a requisitos del tiempo de ejecucin; por su parte, los requisitos del tamao de un vector esttico deben declararse en el tiempo de complicacin. "Los algoritmos recursivos son especialmente apropiados cuando el problema que resolver o los datos que manejar son definidos en trminos recursivos. Los ejemplos en esta seccin ilustran lo que se conoce como "recursin estructural". Este trmino se refiere al hecho de que las subrutinas recursivas se aplican a datos que se definen de forma recursiva. En la medida en que un programador deriva una plantilla de una definicin de datos, las funciones emplean recursin estructural. Es decir, las recursiones en el cuerpo de una funcin consumen una determinada cantidad de un compuesto dado de forma inmediata.1

Listas enlazadas
A continuacin se describe una definicin simple del nodo de una lista enlazada. Ntese como se define el nodo por si solo. El siguiente elemento del nodo del struct es un puntero a un nodo de struct. struct node { int n; // algn tipo de datos

struct node *next; // puntero a otro nodo de ''struct'' };

16

Recursin
// LIST no es otra cosa que un nodo de ''struct'' *. typedef struct node *LIST; Las subrutinas que operan en la estructura de datos de LIST pueden implementarse de forma natural como una subrutina recursiva porque la estructura de datos sobre la que opera (LIST) es definida de forma recursiva. La subrutina printList definida a continuacin recorre la lista hacia abajo hasta que sta se vaca (NULL), para cada nodo imprime el dato (un nmero entero). En la implementacin en C, la lista permanece inalterada por la subrutina printList. void printList(LIST lst) { if (!isEmpty(lst)) { printf("%d ", lst->n); // imprime el entero seguido por un espacio printList(lst->next); // llamada recursiva } } // caso bsico

rboles binarios
Ms abajo se muestra una definicin simple de un nodo de rbol binario. Al igual que el nodo de listas enlazadas, se define a s misma (de forma recursiva). Hay dos punteros que se refieren a s mismos left (apuntando a l aparte izquierda del subrbol) y right (a la parte derecha del subrbol). struct node { int n; // algn tipo de datos

struct node *left; // puntero al subrbol izquierdo struct node *right; // puntero al subrbol derecho

17

Recursin
};

// TREE no es otra cosa que un nodo '' struct '' typedef struct node *TREE; Las operaciones en el rbol pueden implementarse usando recursin. Ntese que, debido al hecho de que hay dos punteros que se referencian a s mismos (izquierda y derecha), esas operaciones del rbol van a necesitar dos llamadas recursivas. void printTree(TREE t) { if (!isEmpty(t)) { // caso bsico

printTree(t->left); // ir a la izquierda printf("%d ", t->n); // imprimir el entero seguido de un espacio printTree(t->right); // ir a la derecha } } El ejemplo descrito ilustra un rbol binario de orden transversal. Un rbol de bsqueda binaria es un caso especial de rbol binario en el cual los datos de cada rbol estn en orden.

Recursin frente a iteracin


En el ejemplo "factorial" la implementacin iterativa es probablemente ms rpida que en la prctica que la recursiva. Esto es casi definido por la implementacin del algoritmo euclideano. Este resultado es lgico, pues las funciones iterativas no tienen que pagar el exceso de llamadas de funciones como en el caso de las funciones recursivas, y ese exceso es relativamente alto en muchos lenguajes de programacin (ntese que mediante el uso de una lookup table es una implementacin an ms rpida de la funcin factorial). Hay otros tipos de problemas cuyas soluciones son inherentemente recursivas, porque estar al tanto del estado anterior. Un ejemplo es el rbol transversal; otros incluyen la funcin de Ackermann y el algoritmo divide y vencers tales como Quicksort. Todos

18

Recursin
estos algoritmos pueden implementarse iterativamente con la ayuda de una pila, pero la necesidad del mismo, puede que anule las ventajas de la solucin iterativa. Otra posible razn para la utilizacin de un algoritmo iterativo en lugar de uno recursivo es el hecho de que en los lenguajes de programacin modernos, el espacio de stack disponible para un hilo es, a menudo, mucho menos que el espacio disponible en elmontculo, y los algoritmos recursivos suelen requerir ms espacio de stack que los algoritmos iterativos. Vase, por otro lado, la seccin siguiente que trata el caso especial de la recursin de cola.

Funciones de recursin de cola


Funciones de recursin de cola son funciones que finalizan con una llamada recursiva que no crea ninguna operacin deferida. Por ejemplo, la funcin gcd (se muestra de nuevo ms abajo) es recursiva de cola; sin embargo, la funcin factorial (que tambin se muestra ms abajo) no es recursiva de cola porque crea operaciones diferidas que tienen que realizarse incluso despus de que se complete la ltima llamada recursiva. Con un compilador que automticamente optimiza llamadas recursivas de cola, una funcin recursiva de cola, como por ejemplo gcd, se ejecutar usando un espacio constante. As, el proceso que genera es esencialmente iterativo y equivalente a usar estructuras de control de lenguaje imperativo como los bucles for y while. Recusin de cola: //Entrada: Los enteros x e y, de forma que x >= y e y > 0 int gcd(int x, int y) { if (y == 0) return x; else return gcd(y, x % y); } Recursin aumento: //Entrada: >= 1 int fact(int n) { if (n == 1) return 1; else return n * fact(n n es un en

entero de forma que n

19

Recursin
1); } La importancia de recursin de cola es que cuando se realiza una llamada recursiva de cola, la posicin de retorno de la funcin que llama necesita grabarse en el call stack; cuando la funcin recursiva retorna, continuar directamente a partir de la posicin de retorno grabada previamente. Por ello, en compiladores que dan soporte a optimizacin de recursin de cola, este tipo de recursin ahorra espacio y tiempo.

Recursin directa e indirecta


Se habla de recursin directa cuando la funcin se llama a s misma. Se habla de recursin indirecta cuando, por ejemplo, una funcin A llama a una funcin B, que a su vez llama a una funcin C, la cual llama a la funcin. De esta forma es posible crear largas cadenas y ramificaciones.

20

Recursin

CONCLUSIONES El poder de la recursin evidentemente se fundamenta en la posibilidad de definir un conjunto infinito de objetos con una declaracin finita. La mayora de los lenguajes de programacin dan soporte a la recursin permitiendo a una funcin llamarse a s misma desde el texto del programa. Crear una subrutina recursiva requiere principalmente la definicin de un "caso base", y entonces definir reglas para subdividir casos ms complejos en el caso base. El algoritmo de bsqueda binaria es un mtodo de bsqueda de un dato en un vector de datos ordenado dividiendo el vector en dos tras cada pasada.

Recursin

RECOMENDACIONES: Investigar acerca recursin en los diferentes lenguajes de programacin. Practicar la recursin en programas de estructura de datos.

Recursin

EGRAFIA http://es.wikipedia.org/wiki/Recursi%C3%B3n_(ciencias_de_computaci%C3%B3n)

You might also like