递归的初步理解(含汉诺塔问题)

递归,按照我的理解就是在没有找到合适的退出条件之前,一直按照某种规律将程序运行下去,直到找到出口,直接将程序操作完,输出.如果没有出口,这个程序将一直循环不会停下,而没有运行条件那也将只进行输出出口操作,两者缺一不可.在这里我先举一个例子

例如用递归求斐波那契数列(ps:斐波那契数列用递归求数据不能太大,我只是举一个例子,实际操作大概四五十程序就算的很慢了,推荐用数组循环储存在取值的方法).

#include<iostream>
using namespace std;
int  fib(int i){
	if(i==1||i==0)return 1;//出口
	else{
		return fib(i-1)+fib(i-2);//递归条件
	}
}
int main(){
	int i;
	cin>>i;
	cout<<fib(i);
}

如图,我们可以把这个拆分成小问题,当等于三的时候,可以理解为:

fib(3)=fib(1)+fib(2).此时可以调用函数本身,进入下一层,又因为i=1已经结束,可以return了,而i=2式子继续递归,式子改变:

fib(3)=1+fib(1)+fib(0).直接计算得到3.以此类推,当i没有满足退出条件,那么就继续按照else里改变,直到可以退出为止,这里也可以知道为什么我之前说数据不能太大,因为他在不停的调用.

其实递归就是一个分解问题的过程,大事化小,由难到易,一层层下来.值得注意的是,当这层循环完了还没有达到退出,直接返回上一层进入的地方.

下面就是经典的递归问题,汉诺塔问题.


描述:

有A,B,C三根针,将A针上N个从小到大叠放的盘子移动到C针,一次只能移动一个,不重复移动,小盘子必须在大盘子上面。

问题:

总的移动次数是多少?输出每次的步骤样式.


我的代码如下:

#include<iostream>
using namespace std;
void hanoi(int n,char A,char B,char C){
	if(n==1){
		printf("%c to %c\n",A,C);//出口
	}
	else{//递归条件
		hanoi(n-1,A,C,B);
		printf("%c to %c\n",A,C);
		hanoi(n-1,B,A,C);
	}
}
int main(){
	int n;
	cin>>n;
	hanoi(n,'A','B','C');
}

首先分析问题,我们要想把整个塔移动到C,又只能一个个的移动,但是又要保证小的在大的上面,那么两根杆子肯定不行,必须借助另外一根杆子,拿两个盘子举例,那么就是:

A to B,用B来暂时放一下小的,

A to C,把大的放在C,

B to C,最后把小的放到大的上面.

这就是最基本的放法,那么,这是否有一定规律呢?

其实,就像小品里面演的一样,把大象放进冰箱,就三步,打开冰箱门,把大象塞进去,关上冰箱门.就是这种思想,把复杂的步骤暂时不看,先看整体,再逐步细化.一开始我不考虑怎样开冰箱门,有多少个步骤开冰箱门,我只看一大步,开冰箱门,汉诺塔问题也是如此,此后所有情况都可以看做上文中两个盘子的情况.

如果n变大,也就是大值按照这种方式,将最大的那个上面盘子的n-1个盘子放到除了起点终点外的"中间人"杆子"上,再将大的放在终点上,最后将充当"中间人"的杆子上n-1个盘子移动到终点上.那么这个时候问题又出来了,如何将步骤细化,其实很简单,你把上面n-1个盘子从A移动到B,其实是一个子问题,这个时候,相较上一层,它的起点和终点都变化了,所以上面的代码,函数后三个参数的顺序意义,分别是起点,中间人,终点.以此类推,我们就开始递归了,每一层都有终点起点,终点起点不停转换,一直到递归出口.

其实递归就是一个将大问题分解为小问题的过程,将一个大问题化成小问题,再将小问题逐个击破,在做递归问题时,我的意见就是先找到规律,把问题按规律一层层化小,这就是递归(个人理解).

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值