递归算法的解析
来源:互联网 发布:淘宝最好的店铺 编辑:程序博客网 时间:2024/05/21 00:50
递归算法
an = an-1 + 1;
你明白这个等式的意义吗?这个等式已经包含了递归算法的全部含义。an 表示 n个数的和,an-1 表示n-1个数的和 ,an = an-1 + 1;表示n个数的和可以通过n-1个数的和来求的。
上述说明哪些情况可以使用递归呢?
那就是:已知前一个步骤可以求得后一个步骤的结果的情况,并且前一个步骤和后一个步骤是有规律的。
比如汉诺塔问题:移n个盘是以移n-1个盘为条件的,两者的共同点是移盘。所以可以用f(n)表示移n个盘,f(n-1)表示移n-1个盘,那么移n个盘和移n-1个盘有什么关系呢?
这就需要预先分析问题才能得出具体的关系在这个问题中,把n个盘从a移到c需要三个步骤来完成。
- 上面n-1个盘从a移到b
- 最后第n个盘从a移到c
- n-1个盘从b移到c
已知n-1个盘从a移到b是可行的,为什么?
因为移1个盘是可行,那么移2个盘也是可行,移 3个盘是以移2个盘为条件的,所以移3个盘也是可行的,所以移n个 盘是可行的。
所以根据已知条件可以解得:
设f(n, a, b,c) 表示 把n个盘从a移到c 借助b 这里很关键,这是搞懂递归的关键关键。
那么把上面n-1个盘从a移到b 借助c 怎样表示呢?很明显是:f(n-1, a, c,b)那么把第n个盘从a移到c怎样表示呢?很明显是:move(n,a,c)
那么把上面n-1个盘从b移到c 借助a 怎样表示呢?
很明显是:f(n-1, b, a,c)
所以f(n, a, b,c) = ( f(n-1, a,c,b) ,move(n,a,c), f(n-1, b,a,c))
这和等差等比数列一个原理。没有什么 特别的。问题有这样递推关系才可以使用这种方法。
如果要你计算1+2+8+22 的结果 你就不能使用递归。因为该问题的后一步骤与前一步骤不具有规律性,所以已知前一个步骤并不能求的后一个步骤的值
1+2+3+4 …这个问题就可以使用递归原因你懂了吧。至于爬楼梯问题,无限级分类 问题等一些递归问题,同理可以解决。
一句话:后一步骤依赖前一步骤并且二者联系具有规律性,运用递归必然成功。
递归算法的应用——汉诺塔的实现
#include<iostream>using namespace std;int numstep = 1;void move(int n, char from, char to) { cout << numstep++ << " : " <<"move "<<n<<" from "<< from << " to " << to << endl;}void hanoi(int n,char from, char depend, char to) { if (n == 1) { move(n, from, to); } else { hanoi(n - 1, from, to, depend); move(n, from, to); hanoi(n - 1, depend, from, to); }}int main() { int a; cin >> a; char x = 'A', y = 'B', z = 'C'; hanoi(a, x, y, z);}
当修改一下汉诺塔的游戏规则:限制不能直接从起始的柱子直接到目的柱子而是一定要经过中间的柱子。
为了使用递归算法实现,就要分析后一步骤和前一步骤的联系。即要把N个盘子移动到目的柱子上怎么通过移上面N-1个盘子(这样就简化了问题)加一些移第N个盘子的步骤来实现。通过分析可以发现如下规律:
- 将1~N-1层盘子先全部从“左”移到“右”
- 将第N层盘子从“左”移到“中”
- 将第1~N-1层盘子全部从“右”移到“左”
- 将第N层盘子从“中”移到“右”
- 最后将1~N-1层盘子全部从“左”移到“右”
#include<iostream>using namespace std;int numstep = 1;void move(int n, char from, char to) { cout << numstep++ << " : " <<"move "<<n<<" from "<< from << " to " << to << endl;}void hanoi_reinforce(int n, char from, char depend, char to) { if (n < 1) return; else { hanoi_reinforce(n - 1, from, depend, to); move(n, from, depend); hanoi_reinforce(n - 1, to, depend, from); move(n, depend, to); hanoi_reinforce(n - 1, from, depend, to); }}int main() { int a; cin >> a; char x = 'A', y = 'B', z = 'C'; hanoi_reinforce(a, x, y, z);}
参考:《程序员代码面试指南》–左程云著
汉诺塔递归全过程
- 递归算法的解析
- 汉诺塔的递归算法与解析
- 汉诺塔的递归算法与解析
- 汉诺塔的递归算法与解析
- 汉诺塔的递归算法与解析
- 汉诺塔的递归算法与解析
- 二叉树的递归遍历算法解析
- 深入解析递归算法
- KMP算法之我见(NEXT数组的递归解析)
- 最简化约瑟夫环问题的递归算法详细解析
- 个人最容易理解的汉诺塔算法解析(递归算法),通俗易懂,强烈推荐
- 递归算法解析树形结构表
- java 快速排序递归算法详细解析
- 从递归算法思想解析汉诺塔问题
- java 解析xml 递归算法 简单实用
- fft的递归算法
- 排列组合的递归算法
- 背包的递归算法
- 你是被别人整还是整别人
- ZOJ 3605Find the Marble
- Fragment
- java中如何将char数组转化为String?
- ZOJ 3607Lazier Salesgirl
- 递归算法的解析
- Android笔记--解决使用php文件插入数据到mysql数据库的表中中文变问号的问题
- 深入理解Servlet [转]
- 用windeployqt打包Release版本后提示错误
- 6.2016.物电学院 电气工程及其自动化 辛雅松 15050341033
- 泛型
- Java继承、多态面试题
- php字符串函数
- ScrollView 滚动条知识点