标签:递归的理解
1.什么是递归?
递归就是直接或间接的调用自己
2.怎么对一个问题建模并转化为递归的形式?
这个问题就大了,首先建模这个东西已经超出了程序员的范畴,那其实是数学的一部分。
3.那么是不是一点办法都没有呢
经过书上的讲解,上课老师的讲解,视频讲解,网上资料的讲解,现在对待递归的本质有了更深入的认识了
对于一些简单地问题,我们如何建模!找几个例子,然后继续总结!
例1:,就是阶乘,如何建模使用递归!
当n=1时,1的阶乘是1;
当n=2时,2的阶乘是1*2;
当n=3时,3的阶乘是1*2*3;
所以函数表达式可以写成 n!=n*(n-1)!(n>1) n=1时,1!=1(这个有些书上讲这个是边界条件,或者是出口)
diGui(int n)
{
if(n==1)
return 1;
diGui(n-1)*n;
}
例2:斐波那契数列也是这个样子的!(找到其边界条件,2个,f1=1,f2=1)
例3:汉诺塔问题?(这里我就不再叙述它的规则了,直接建模)
有3个柱子分别是ABC,盘子由小到大分别用1,2,3表示
当盘子只有1个的时候,直接从盘子A移动到盘子C
当盘子只有2个的时候,先是将盘子1,通过C,移动到B
然后将盘子2,直接移动到C
最后将盘子1,通过盘子移动到C上
当盘子只有3个的时候,先将1.2盘子,通过C,移动到B(和当n==2的情况一样)
然后将盘子3,直接移动到C
最后将盘子1,2,移动到到C上
当有n个盘子的时候,现将n-1个盘子,通过C,移动到B
然后将盘子n,直接移动到C
最后将盘子n-1,通过A,移动到到C上
表达式:hannuota(int n,char a,char b,char c)
{
if(n==1)
move(a,c);
hannuota(n-1,a,c,b)
move(n,a,b,c)
hannuota(n-1,c,a,b);
}
总结:建模都是从当n=1时候,开始的总结,n=2时候是什么样子,n=3,有将会是多少,
另外观察当n=3,是否是在2的基础上运行的(是看他们的思想),看3模型,在2的思想和2在1的思想上是否是匹配的,如果匹配可以使用递归,如果不匹配那不符合递归,递归和面向对象一样都是一种模型,就看你匹不匹配。如果匹配就可以用递归(模型匹配)
我在举个二叉树的先序遍历的例子。
3个节点的时候,头结点,左结点,右结点。(n=1)
7个节点的时候,头结点,然后是左结点全部遍历完之后,然后是右结点,而不是在3个节点基础上继续遍历剩余的结点,难道是否不匹配,不是,其实是已经分叉了,递归它的里面已经有多分支递归了。从左子树开始的时候,开始类似于3个节点的时候,这边是模式匹配,这已经是多分支了,同样右结点开始的时候也是3个节点的类似,这又匹配,所以多分支了。递归只要设计出两部,后面的就基本不用看了,只要校验一下,看看对不对,证明是很难证明的,有点类似于数学归纳法。
//以上自底向上的逻辑思考方式:
//下面通过自顶向下的逻辑思考方式:
如何遍历二叉树:试想下如果这颗二叉树非常复杂,西遍历头部,头部遍历完了,在遍历左边,左边遍历完了在遍历右边。发现左边又很复杂,先遍历左边的头,在遍历左边的左边,在遍历右边的右边。
递归算法如何思考编写?
函数名
{
遍历头
遍历左边
{
先遍历头
遍历左边头 --->这不应该还是函数名吗?//执行流程思想全是一样的。
遍历右边头
}
遍历右边
{
遍历头
遍历左边 --->这不应该还是函数名吗?//执行流程思想全是一样的。
遍历右边
}
}
关于递归的写法,总之要有个出口。也就是边界条件。
第二个就是设计递归函数表达式。
本文出自 “简答生活” 博客,转载请与作者联系!
标签:递归的理解
原文地址:http://1464490021.blog.51cto.com/4467028/1864934