Una llamada de función recursiva de cola permite al compilador realizar una optimización especial que normalmente no puede con recursión regular. En una función recursiva de cola, la llamada recursiva es lo último que se ejecuta. En este caso, en lugar de asignar un marco de pila para cada llamada, el compilador puede reelaborar el código para simplemente reutilizar el marco de pila actual, lo que significa que una función recursiva de cola solo usará un solo marco de pila en lugar de cientos o incluso miles.
Esta optimización es posible porque el compilador sabe que una vez que se realiza la llamada recursiva de la cola, no se necesitarán copias previas de variables, porque no hay más código para ejecutar. Si, por ejemplo, una declaración de impresión siguió una llamada recursiva, el compilador necesitaría saber el valor de la variable que se imprimirá después de que las llamadas recursivas se devuelvan y, por lo tanto, el marco de la pila no se puede reutilizar.
Aquí está la página Wiki si desea obtener más información sobre cómo funciona este "ahorro de espacio" y la reutilización de la pila, junto con ejemplos: Llamada de cola
EDITAR: No expliqué cómo se aplica esto a QuickSort, ¿verdad? Bueno, algunos términos se lanzan en ese artículo que hacen que todo sea confuso (y algunos de ellos son simplemente incorrectos). La primera función dada (QuickSort) hace una llamada recursiva a la izquierda, una llamada recursiva a la derecha y luego sale. Observe que la llamada recursiva a la derecha es lo último que sucede en la función. Si el compilador admite la optimización recursiva de la cola (explicada anteriormente), solo las llamadas a la izquierda crean nuevos marcos de pila; Todas las llamadas correctas solo reutilizan el marco actual. Esto puede salvar alguno marcos de pila, pero aún puede sufrir el caso en el que la partición crea una secuencia de llamadas donde la optimización de la recursión de la cola no importa. Además, a pesar de que las llamadas del lado derecho usan el mismo cuadro, las llamadas del lado izquierdo llamaron dentro de Las llamadas del lado derecho todavía usan la pila. En el peor de los casos, la profundidad de la pila es N.
La segunda versión descrita es no Una rápida cola recursiva, sino una rápida que solo la clasificación izquierda se realiza de manera recursiva, y la clasificación correcta se realiza usando el bucle. De hecho, este QuickSort (como lo describió anteriormente otro usuario) no puede tener la optimización de la recursión de la cola aplicada a ella, porque la llamada recursiva no es lo último que se ejecuta. ¿Como funciona esto? Cuando se implementa correctamente, la primera llamada a QuickSort es la misma que una llamada del lado izquierdo en el algoritmo original. Sin embargo, no se llaman llamadas recursivas del lado derecho. ¿Como funciona esto? Bueno, el bucle se encarga de eso: en lugar de clasificar "a la izquierda y luego a la derecha", clasifica la izquierda con una llamada, luego clasifica la derecha clasificando continuamente solo solo el Lefts de la derecha. Es realmente ridículo sonar, pero básicamente es solo clasificar tantas izquierdas que los derechos se convierten en elementos individuales y no necesitan ser ordenados. Esto elimina efectivamente la recursión correcta, lo que hace que la función sea menos recursiva (pseudo recursiva, si lo desea). Sin embargo, la implementación real no elige solo el lado izquierdo cada vez; Elige el lado más pequeño. La idea sigue siendo la misma; Básicamente solo hace una llamada recursiva en un lado en lugar de ambos. Recoger el lado más corto asegurará que la profundidad de la pila nunca pueda ser más grande que Log2 (N), que es la profundidad de un árbol binario adecuado. Esto se debe a que el lado más corto siempre será como máximo la mitad del tamaño de nuestra sección de matriz actual. Sin embargo, la implementación dada por el artículo no garantiza esto, ya que puede sufrir el mismo peor de los casos de "la izquierda es todo el árbol". Este artículo realmente da una buena explicación si está dispuesto a leer más: Selección eficiente y clasificación parcial basada en QuickSort