简体   繁体   中英

recursive stack overflow in fibonacci function

I'm triying to understand the stack overflow mecanism of a recursive function. So i used this fibonacci function :

def fib(n):
 if n==1 or n==2:
    return 1
 return fib(n-1)+fib(n-2)
print (fib(555))

when i try this function to calcualte fibo(999) i've got this RuntimeError: maximum recursion depth exceeded in comparison but when i try to calculate fibo(555) python does not print any runtime error but still work

I know that the default recursive deeptHs in python is 1000 but i don't understant why python does'n print a run time error when i try to find fibo (555)

THK'X FOR ALL

It may be that the limit is on stack depth rather than number of recursive calls, and you may well have used up some of that stack depth before the first call to fib() .

With fib(555) , you'll only be adding 555 stack frames, not 555 + 554 . That's because the two terms of the calculation are done sequentially. In other words, fib(555) is called and that uses 555 stack frames to do its work, then, and this is important, unwinds those frames so you're back at the stack level you were at before calling fib(555) . Then fib(554) is called and it uses about the same number of frames.

At no stage are you using more than the extra 555 stack frames. So, graphically, it's not doing:

_                                      _
 \                                    /
  \           (555 levels)           /
   \__                            __/
      \                          /
       \  (another 554 levels)  /
        \______________________/

What it is doing is:

_       _     _
 \     / \   /  (555 levels down, then
  \   /   \_/    back up, then down
   \_/           554, then back up again)

In any case, using recursion to calculate Fibonacci numbers is incredibly inefficient since, for 999 , you calculate fib(998) twice, one as part of the first term fib(999) ( 998 being done one stack level down) and one as the second term fib(998) . Then, for each of those two fib(998) calls, you calculate fib(997) twice. This is a horrendously time-expensive way of doing it, with the runtime rising quadratically (the term may be wrong, and those with more mathematical nous can correct me, but what I mean is that it rises with the square of the number).

Far better to use an iterative solution, such as the following pseudo-code (which, by no mistake, looks a lot like Python, since Python is an ideal pseudo-code language):

# Calculate Fibonacci, first term fib(0).

def fib(n):
    if n <= 1: return 1
    grandparent = 1
    parent = 1
    for i in range(n - 1):
        me = parent + grandparent
        grandparent = parent
        parent = me
    return me

for i in range(10):
    print i, fib(i)

This is much more efficient than the recursive solution and has no issues with stack overflow. It returns fib(999) almost instantly:

70330367711422815821835254877
18354977018126983635873274260
49050871545371181969335797422
49494562611733487750449241765
99108818636326545022364710601
20533741212738673391111981393
73125598767690091902245245323
403501

as opposed to the full ten minutes I waited for the recursive solution before I got bored and wandered off.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM