记住经典的斐波拉契递归和阶乘递归转换为while规律
记住经典的斐波拉契递归和阶乘递归转换为while规律.它为实现更复杂转换提供了启发性思路.
# 斐波拉契--树形递归 def fab(n): if n<3: return n return fab(n-1)+fab(n-2) def wfab(n): stacks=[(0,n,None)] while stacks: stg,n,value=stacks.pop() if stg==0: if n<3: res=n else: stacks.append((1,n,None)) stacks.append((0,n-1,None)) elif stg==1: stacks.append((2,n,res)) stacks.append((0,n-2,None)) else: res=value+res return res #阶乘--线性递归 def fac(n): if n<1: return 1 return n*fac(n-1) def wfac(n): stacks=[(0,n)] while stacks: stg,n=stacks.pop() if stg==0: if n<1: res=1 else: stacks.append((1,n)) stacks.append((0,n-1)) elif stg==1: res=res*n return res
理解了原理,即每出现一次递归调用,先对当前栈做一个记号,再创建一个新栈,对应递归调用.比如,将fab略微改变一下,有更多系数,操作符和递归调用,次序也不是按照n-1,n-2这样来,也能比较容易地模拟出来:
def fab(n): if n<4: return n return (3*fab(n-3)-2*fab(n-1))*4*fab(n-2)
仿照上面可转化为:
def wfab(n): stacks=[(0,n,None)] while stacks: stg,n,value=stacks.pop() if stg==0: if n<4: res=n else: stacks.append((1,n,None)) stacks.append((0,n-3,None)) elif stg==1: stacks.append((2,n,3*res)) stacks.append((0,n-1,None)) elif stg==2: stacks.append((3,n,value-2*res)) stacks.append((0,n-2,None)) else: res=value*4*res return res
再如:
arr=[1,5,10,25,50] def xch(my,ars): if my==0: return 1 if my<0 or not ars: return 0 return xch(my,ars[1:])+xch(my-ars[0],ars)
def xch2(my,ars): stk=[(0,my,ars,None)] res = 0 while stk: stg,my,ars,value = stk.pop() if stg==0: if my==0: res = 1 elif my<0 or not ars: res = 0 else: stk.append((1, my, ars, None)) stk.append((0, my, ars[1:], None)) elif stg==1: stk.append((2, my, ars, res)) stk.append((0, my-ars[0], ars, None)) else: res = res + value return res