说说回溯
说说回溯
def f(x):
global sum
if x == 0:
return 0
else:
sum = f(x - 1) + x
sum = sum - x
print sum
return sum
print '===='
print(f(100))
print '-----'
以这个代码为例,因为这里的累加是递归到0之后返回然后从0累加到100,而回溯是返回时,也就是返回时+x同时又-x 所以结果是0
全排列的回溯
import copy
numlist = [1,2,3]
container = []
all=[]
def traceback(numlist):
for i in numlist:
if len(container) == 3:
print 'the size is ready '
print container
new = copy.deepcopy(container)
all.append(new)
print all
return
if i in container:
print 'i:%s has in list' %(i)
continue
else:
print 'append %s' %(i)
container.append(i)
print 'start call fun trackback:'
traceback(numlist)
print 'before the traceback container value is:%s' %(container)
t = container.pop()
print 'after the traceback pop the value is: %s, container value is: %s' %(t,container)
print 'after the traceback the container :%s' %(container)
//全排列是多路选择,迭代和递归相互螺旋叠加调用,所以看起来情况比较复杂。
迭代调用递归,递归又调用迭代中的递归
它整体的执行特性有几个特点:多路迭代调用递归并发执行、螺旋向下递归,并且部分迭代并发递归是被阻塞在递归调用里,得等回溯了才能继续执行。
比如: 当numlist= [1,2,3]
for i in numlist:
if i in container:
print 'i:%s has in list' %(i)
continue
else:
print 'append %s' %(i)
container.append(i)
print 'start call fun trackback:'
traceback(numlist)
每次多路选择的迭代都会递归同样的numlist序列。
在递归的逻辑里我们加了递归的过滤条件和终止条件,当不符合过滤条件则进行递归,这时迭代的递归会因为向下递归的逻辑没执行后,后续的迭代序列递归被阻塞在先前的序列递归上,只有等整个函数回溯了才得已继续。
比如for i in [1,2,3] 当2满足不在container条件,这时container.append(2),继续走traceback(numlist).向下递归,同时阻塞[1,2,3]序列的3
只有当满足if len(container) == 3:条件时,才会进行回溯,回溯时会执行container.pop(),并且还会回到刚刚阻塞的迭代序列里继续执行。
当满足if len(container) == 3时,container.pop(3),然后又pop(2),继续执行for i in [1,2,3](此时i=3).
这也说明了为什么组合里有1,2,3还能有1,3,2。
1,3,2由两块逻辑共同完成,一块是回溯的pop逻辑,一块是多路选择的迭代组合(因为前面的迭代被阻塞,返回时继续)
代码图示
