递归

一、概念

直接或间接调用自身的算法称为递归

二、条件

(1)给递归定义的初始值

(2)用较小的自变量的函数值来表示较大自变量的函数值

三、思想

  问题规模较大,解决该问题时较困难。因此考虑将问题规模较大的问题分割成一些规模较小的相同的子问题,反复使用这种方式,直至使子问题缩小到极易求解。得出答案的过程为逆过程,先解决规模较小的极易求解的子问题,然后依次扩大问题规模,直至得出问题答案。

四、例子

(1)阶乘函数

n!={1n(n1)!n=0n>0

实现代码


 1. int factorial(int n)
 2. {
 3.     if(n == 0) return 1;
 4.     return n * factorial(n - 1);
 5. }

  定义域n为非负值,递归的第一式给出了函数初始值,是非递归定义的,第二式给出了用较小自变量函数值来表示较大自变量函数值的方式来定义n的阶乘。

(2)Fibonacci数列

F(n)=11F(n1)+F(n2)n=0n=1n>1

实现代码


 1. int fibonacci(int n)
 2. {
 3.     if(n <= 1) return 1;
 4.     return fibonacci(n - 1) + fibonacco(n - 2);
 5. }

递归的实现从第三项开始,后一个数是前两个数的和。

(3)排列问题
   Ri={r1,r2,rn} 是要进行排列的n个元素, Ri=R{ri} 。集合X中元素的全排列记为 Perm(X) (ri)Perm(X) 表示在全排列 Perm(X) 的每一个排列前加上前缀 ri 得到的排列。 R 的全排列可归纳定义为:
  当n=1时, Perm(R)=(r) ,其中 r 是集合R中唯一的元素。
  当 n>1 时, Perm(R) Perm(R1) , (r2)Perm(R2) ,
, (rn)Perm(rn) ,构成。

实现代码


 1. template<typename T>
 2. void Perm(T list[], int k, int m)
 3. {  //产生list[k:m]的所有排列
 4.     if(k == m) {
 5.         //只剩1个元素
 6.         for(int i = 0; i != m; ++i)
 7.             cout << list[i];
 8.         cout << endl;
 9.     } else {  //还有多个元素待排列,递递归产生排列
 10.         for(int i = k; i != m; ++i) {
 11.             Swap(list[k], list[i]);
 12.             Perm(list, k + 1, m);
 13.             Swap(list[k], list[i]);
 14.         }
 15. }

Swap函数代码


 1. template<typename T>
 2. inline void Swap(T &a, T &b)
 3. {
 4.     T temp = a;
 5.     a = b;
 6.     b = temp;
 7. }

  实现过程如下图所示,以a元素为例,实现过程如图左,总排列结果如图右。

全排列

(4)Hanoi塔问题

Hanoi塔问题
   如图所示,要求将A上的圆盘移动到B上,上面小圆盘下面大圆盘的顺序不变。

实现代码


 1. void hanoi(int n, int a, int b, int c)
 2. {
 3.     if(n > 0) {
 4.         hanoi(n - 1, a, c, b);
 5.         move(a, b);
 6.         hanoi(n - 1, c, b, a);
 7.     }
 8. }

  实现过程为首先将A中除最下面的圆盘移动到C上(借助B),然后将A中最下面的圆盘移动到B上,之后将C上的圆盘按顺序移动到B上(借助A)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值