import time # 斐波那契傳統遞歸方法,屬於二路遞歸,重複計算數值,計算效率很是低,隨着n的增大,須要遞歸的次數將呈指數級增加 def bad_feibo(n): if n <= 1: return 1 return bad_feibo(n-1)+bad_feibo(n-2) # 在返回結果時,將前一個值順帶回來,這樣隨着n的增大,須要遞歸的次數呈線性增加,該優化將能大大提高遞歸效率 def good_feibo(n): def imp_feibo(n): if n <= 1: return (0, 1) a, b = imp_feibo(n-1) return (b, a+b) return sum(imp_feibo(n)) start = time.time() a = bad_feibo(36) print('bad_feibo: %s time: %s' % (a, time.time()-start)) start = time.time() b = good_feibo(36) print('good_feibo: %s time: %s' % (b, time.time()-start)) # bad_feibo: 24157817 time: 4.94177293777 # good_feibo: 24157817 time: 1.90734863281e-05 # 計算某個數的指數結果,隨着指數的增長,須要遞歸的次數呈線性增加,屬於線性遞歸 def bad_exp(x, r): def imp_exp(r): if r == 0: return 1 return x*imp_exp(r-1) return imp_exp(r) # 利用乘法的特性,隨着指數的增長,須要遞歸的次數呈現對數增加,屬於線性遞歸,在該例子中,優化的結果爲計算時間少了一個數量級 def good_exp(x, r): def imp_exp(r): if r == 0: return 1 if r == 1: return x mid = r // 2 rst = imp_exp(mid) rst = rst*rst if r % 2 == 1: rst *= x return rst return imp_exp(r) start = time.time() a = bad_exp(2, 100) print('bad_exp: %s time: %s' % (a, time.time()-start)) start = time.time() b = good_exp(2, 100) print('good_exp: %s time: %s' % (b, time.time()-start)) # bad_exp: 1267650600228229401496703205376 time: 5.50746917725e-05 # good_exp: 1267650600228229401496703205376 time: 5.96046447754e-06