同学对于递归一直不能理解
递归? 循环?
首先
这里有一个奇怪的故事
很久以前
有一位老爷爷讲了一个故事 , 故事讲了很久以前 , 有一位老爷爷讲了一个故事 , 故事讲了 , ……
我们很容易看出
我吃饭了
吃完饭了 , 我吃饭了 。 吃完饭了 , 。 ……
这个例子同样的是由一句话重复得来的
但不同的是
第一个例子
递归的边界条件
定义很简单
来个例子吧
阶乘的递归实现
:
int factorial(int N) {
if (N == 1)
return 1;
return N * factorial(N-1);
}
数学上的递推式f(x)=x*f(x-1),f(1)=1
在这里N==1
递归的过程
程序运行的步骤如下
factorial(4)
= 4 * factorial(3)
= 4 * (3 * factorial(2) )
= 4 * (3 * (2 * factorial(1) ) )
= 4 * (3 * (2 * 1) )
= 4 * (3 * 2)
= 4 * 6
= 24
也可以是
factorial(4)
factorial(3)
factorial(2)
factorial(1)
return 1
return 2*1 = 2
return 3*2 = 6
return 4*6 = 24
4-> 一开始N*factorial(N-1)
4*factorial(3)
3-> 那么3*factorial(2)
2-> 聪明的你很快就能想到2*factorial(1)
1-> 运行到
2-> 这时视线回到2*1=2
3-> 那么3*factorial(2)=3*2=6
4-> 再回到一开始的4*6=24
上面这一大段文字就是程序运行的步骤的详解
而虽然每次乘法的值都不同
递归的变量问题
经过我这么这么一大段的废话之后
比如
我们看看下面两个函数
void a() {
int k=1;
b();
cout << k << endl;//这里输出多少呢?
}
void b() {
int k=2;
cout << k << endl;//这里输出多少呢?
}
其实如果你基础好的话很容易得出结果
int k;
void a() {
k=1;
b();
cout << k << endl;//这里输出多少呢?
}
void b() {
k=2;
cout << k << endl;//这里输出多少呢?
}
而在这个例子中就都是
对于递归来说
所以在
递归&循环
再来说一下递归与循环的区别吧
循环是广度的
而递归不同
每一次的递归都是层叠
所以
递归总结
最后概括一下
- 它有一个基本部分
即直接满足条件, 得到结果, 边界条件( ) - 它有一个递归部分
即 通过改变基数, 即( ) 来逐步使得, 从而得到结果, - 每一步操作
整体都会将部分当作其必要的一个步骤, 从而实现整体步骤的完成,
引用资料
http://blog.csdn.net/jinghouxiang/article/details/50583819 :
http://blog.csdn.net/speedme/article/details/21654357
搜索算法
终于讲完递归了
让我们来看一道简单的题
给定一个整数
N 输出 , 1-N 的全排列
若
这时我们的代码很好写
for (int i=1;i<=3;i++)
for (int j=1;j<=3;j++)
for (int k=1;k<=3;k++)
if (i!=j && i!=k && j!=k)
printf("%d %d %d\n", i, k, j);
随意暴力搞搞就行
基于我们之前研究得到的递归的特性
if (当前递归层数==N+1) //为什么是 N+1? 自行思考
返回
for i=1 到 N
{
输出 i
递归( 当前层数+1)
}
这样就解决了
但是
在上面的例子我们是判断几个循环变量全部不同来判断的
我们可以采用用一个数组记录下来哪些数选过
基于这个思路
if (当前递归层数==N+1) //为什么是 N+1? 自行思考
返回
for i=1 到 N
{
if( 当前 i 用过) //因为全排列中每个数只能出现一次
跳过当前循环
输出 i
记录 i 用过
递归( 当前层数+1)
还原 i 变成没用过 //关键, 为什么要还原一下?
}
这样就构成了一个完整的搜索与回溯结构
在代码中
因为如果不还原
为了还能有数在返回后继续递归
那么
bool book[25];
int n;
void dfs(int step)
{
if (step==N+1) //step 代表的是当前的递归的层数。 dfs(1) 就代表在选第一个数, dfs(2) 就是在选第二个数
return;
for (int i=1;i<=n;i++)
{
if (book[i])
continue;
cout << i;
book[i]=true;
dfs(step+1); //递归下一层
book[i]=false; //回溯
}
}
其中
看到这里
当然
这时