递归在算法中很常见,比如下面两个例子。
A-program
// 二叉树中序递归版本
visit(root){
if root==null; return
visit(root.left) // 左树
print(root) // 根
visit(root.right) // 右树
}
sum(n)求和:
B-program
// 递归版本求和
f(n){
if n=1 ;return 1
return n+f(n-1)
}
在算法设计中,递归由于调用栈过深,资源得不到释放,性能较差,往往需要转换为迭代版本,理论上,可以证明,迭代和递归是可以相互转换的。
递归改迭代,是回溯算法的具体应用。在迭代版本中,我们很大可能会用到栈的数据结构,来以此模拟函数的调用过程。在迭代中,需要我们显示存储当前节点和路径。B是单路递归(尾递归),A是多路递归,B是A的一个特例。
A迭代版本:
visit(root){
stack,root // 存储路径和当前节点
// 有节点没有访问到或者回溯到
while(stack.size()>0 || root !=null){
while(root!=null){
stack.push(root)
root.left
}
// 没有左节点后就开始回溯
cur = stack.pop()
print(cur)
root = cur.right
}
}
B迭代版本:
其实,最能体现回溯算法的威力例子就是树的遍历:preOrder,inOrder,postOrder三种遍历方法。
##回溯算法模板