¿Cuáles son los beneficios de usar la recursividad de la cola? ¿Es siempre posible?

La recursividad de la cola es funcionalmente equivalente a un simple ciclo while.

Pruébelo usted mismo: tome una función recursiva de cola y escriba un bucle while equivalente.

Los compiladores inteligentes lo saben y crearán un código similar para el bucle while y la implementación recursiva de cola, evitando así la pila de funciones normal.

Para las funciones recursivas que no utilizan la recursividad de cola, tiene alguna expresión compleja con algunos otros términos. Y necesita almacenamiento adicional para los resultados parciales de esos otros términos cada vez que realiza la llamada recursiva, es decir, necesita una pila que crece cada vez que entra en la recursividad.

Por supuesto, siempre puede poner esta pila en un argumento adicional (a menudo llamado acumulador) y, por lo tanto, obtener una función recursiva de cola, pero en este caso no gana nada ya que la pila todavía está allí; ahora está explícitamente administrada por usted, en lugar de compilador.

En algunos casos, creo que si el operador calculado por la expresión compleja es asociativo y tiene un elemento neutral, también puede hacerlo sin una pila. En esos casos tienes mucha suerte.

La recursividad de cola elimina el espacio de pila O (n) requerido para almacenar argumentos de función en la memoria cuando se realizan llamadas recursivas; la “n” aquí se refiere al número de llamadas recursivas realizadas antes de llegar al caso base. Convierte ese espacio de pila O (n) en espacio de pila O (1) reutilizando el marco de pila para cada llamada recursiva en lugar de crear uno nuevo para cada llamada. Si bien esta es una gran optimización de espacio, no siempre es posible; La recursión de cola solo se aplica si no hay instrucciones que siguen a la llamada recursiva.

Considere el siguiente código trivial para imprimir una cadena un carácter a la vez:

impresión vacía pública (String s) {
if (s.length () == 0) {return; }
System.out.println (s.charAt (0));
print (s.substring (1)); / * Corta el primer personaje * /
}

Observe cómo la llamada recursiva a la función print () es la última; de ahí proviene la “cola” en “recursión de cola”. El compilador verá esto y se dará cuenta de que no tiene sentido almacenar la pila de llamadas de función en la memoria porque no la necesitamos.

Ahora considere este código trivial para imprimir una cadena un carácter a la vez en reversa :

public void printReverse (String s) {
if (s.length () == 0) {return; }
printReverse (s.substring (1)); / * Corta el primer personaje * /
System.out.println (s.charAt (0));
}

Tenga en cuenta que todo lo que hemos hecho es intercambiar las líneas 3 y 4 del código. En este caso, el compilador se da cuenta de que hay instrucciones que siguen a la llamada recursiva; en otras palabras, la pila de llamadas a funciones debe recordarse para que podamos recordar a dónde regresar una vez que se haya ejecutado la instrucción posterior.

PD

Tenga en cuenta que estos fragmentos de código se usan solo para demostraciones simples de recursión. No tome estos fragmentos como ejemplos de buenas prácticas de codificación; Esta no es la forma óptima de implementar estas funciones.

More Interesting

¿Cómo crean los algoritmos los programadores de software?

¿Es mejor hacer InterviewBit ahora (actualmente estoy en mi quinto semestre) o hacer SPOJ ahora y luego hacer InterviewBit solo 3 o 4 meses antes de las entrevistas? Solo conozco algunas estructuras de datos y algoritmos básicos. He hecho 40 problemas en SPOJ.

¿Qué son las estructuras de datos y los algoritmos en c ++?

¿Podría haber estándares de cifrado que descansen en un problema NP-hard distinto de la factorización entera?

¿Por qué el ordenamiento rápido se denomina 'rápido' incluso cuando tiene complejidad O (n2) en el peor de los casos?

Cómo evaluar el efecto del programa de seguridad vial en el comportamiento después de 7 años de implementación si no hay datos de referencia

¿Qué es el algoritmo de optimización de memoria?

¿Cómo funciona el algoritmo what3words?

Cómo escribir un programa para encontrar la frecuencia de la presencia de un elemento en una matriz en C ++

¿Cómo manejan los sistemas de reputación los sesgos (sistémicos) que pueden distorsionar significativamente las clasificaciones basadas en tales sistemas?

¿La comprensión humana sigue un algoritmo de compresión de datos?

Cómo probar si una cadena es una subcadena de otra cadena en C sin ninguna función incorporada

¿El aprendizaje por refuerzo está recibiendo actualmente más atención que los algoritmos genéticos?

Cuando quitamos un borde de un árbol, parece obvio que nos quedan dos árboles, pero ¿cómo podríamos probar esto?

Dos jugadores juegan el siguiente juego: hay N piedras en la mesa, el jugador puede tomar 1 o 2 piedras (si N mod 3 = 0), 1 o 3 (si N mod 3 = 1) y 1, 2 o 3 ( si N mod 3 = 2). ¿Cómo determino al ganador en el juego?