Nói một cách đơn giản, đệ quy đuôi là một đệ quy trong đó trình biên dịch có thể thay thế cuộc gọi đệ quy bằng lệnh "goto", vì vậy phiên bản đã biên dịch sẽ không phải tăng độ sâu ngăn xếp.
Đôi khi thiết kế một hàm đệ quy đuôi đòi hỏi bạn cần tạo một hàm trợ giúp với các tham số bổ sung.
Ví dụ, đây không phải là một hàm đệ quy đuôi:
int factorial(int x) {
if (x > 0) {
return x * factorial(x - 1);
}
return 1;
}
Nhưng đây là một hàm đệ quy đuôi:
int factorial(int x) {
return tailfactorial(x, 1);
}
int tailfactorial(int x, int multiplier) {
if (x > 0) {
return tailfactorial(x - 1, x * multiplier);
}
return multiplier;
}
bởi vì trình biên dịch có thể viết lại hàm đệ quy thành hàm không đệ quy, sử dụng cái gì đó như thế này (mã giả):
int tailfactorial(int x, int multiplier) {
start:
if (x > 0) {
multiplier = x * multiplier;
x--;
goto start;
}
return multiplier;
}
Quy tắc cho trình biên dịch rất đơn giản: Khi bạn tìm thấy " return thisfunction(newparameters);
", hãy thay thế nó bằng " parameters = newparameters; goto start;
". Nhưng điều này chỉ có thể được thực hiện nếu giá trị được trả về bởi lệnh gọi đệ quy được trả về trực tiếp.
Nếu tất cả các cuộc gọi đệ quy trong một hàm có thể được thay thế như thế này, thì đó là một hàm đệ quy đuôi.