فاکتوریل بازگشتی
n! = n · (n−1)! سادهترین مثال بازگشت: فراخوانیها تا حالت پایه روی پشته جمع میشوند و بعد در برگشت ضربها انجام میشود.
n! = n · (n−1) · … · 1 را میشود بازگشتی نوشت: n! = n · (n−1)! و 0! = 1! = 1. هر الگوریتم بازگشتی دو بخش دارد:
- زمان:
O(n) - حافظه:
O(n) - جانسونباو، فصل ۴
- گریمالدی، فصل ۴
5! = 120؛ پنج فراخوانی روی پشته میروند و در برگشت ضرب میشوند.
def factorial(n):if n <= 1:return 1rest = factorial(n - 1)return n * rest
شروع اجرا
n5
rest—
درخت فراخوانیهای بازگشتی
نارنجی پر = فراخوانی در حال اجرا · حاشیهی نارنجی = هنوز روی پشته · خاکستری = تمام شده
متغیرهای محلی
n5
نارنجی = در همین گام عوض شد
Call stack
- factorial()خط 1
گام ۱ از ۱۹
توضیح
ایده
n! = n · (n−1) · … · 1 را میشود بازگشتی نوشت: n! = n · (n−1)! و 0! = 1! = 1. هر الگوریتم بازگشتی دو بخش دارد:
- حالت پایه که بدون بازگشت جواب میدهد؛
- گام بازگشتی که مسئله را به نمونهی کوچکتری از خودش تبدیل میکند.
پشتهی فراخوانی
فراخوانیها تا رسیدن به حالت پایه روی پشته جمع میشوند (n فریم)، بعد یکییکی برمیگردند و ضربها در برگشت انجام میشوند. برای همین حافظه O(n) است، در حالی که نسخهی حلقهای O(1) حافظه دارد.
در trace به چه چیزی نگاه کنی
- پنل پشتهی فراخوانی را ببین: چند فریم
factorialباnهای متفاوت همزمان زندهاند.