递归算法的理解

递归算法的理解

To Iterate is Human, to Recurse, Divine.
人理解迭代,神理解递归。
当第一次看到汉诺塔(Hanoi)如此简洁的算法时,你不得不被递归的魅力所吸引,是那样的简洁。我想它的迷人之处正是在于用有限的语句来定义对象的无限集合

递归:程序调用自身的编程技巧称为递归( recursion)。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。 ----百度百科

如我们所熟知的斐波那契数列的定义就是具有递归特性:

  • 0, n=0
  • 1, n=1
  • Fib(n-1)+Fib(n-2), n>1

那么现在我们要如何计算后面的函数值呢,比如:
Fib(100)=?

首先,我们知道
Fib(0)=0
Fib(1)=1
Fib(100)=Fib(99)+Fib(98);
Fib(99)=Fib(98)+Fib(97);

如此往复,当最终化为Fib(0)和Fib(1)时,然后将值带进去。
最终得出我们想要的答案

用c语言描述:

int  Fib(int n)//斐波那契函数
{
   if(n==0) 
     return 0;
   else if (n==1) 
     return 1;
   else
   return Fib(n-1)+Fib(n-2);
}

我们现在能够发现这个函数实质上包含两个过程,递去(不断深入递归的层数),再归来。
递归实质上分为两个过程:
递去:将递归问题分解为若干个规模较小,与原问题形式相同的子问题,并且这些子问题可以用相同的解题思路来解决。

归来:当你将问题不断递去的时候,必须有一个明确的结束递去的临界点(递归出口),一旦达到这个临界点即从该点返回,最终解决。
递 和 归,这正是递归的精华所在!
知道了递归的含义,我们来比较一下循环和递归的区别:
先对递归和循环形象化的描述:
递归你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,你继续打开它。若干次之后,你打开面前的门后,发现只有一间屋子,没有门了。然后,你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这你把钥匙打开了几扇门。

循环你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门(若前面两扇门都一样,那么这扇门和前两扇门也一样;如果第二扇门比第一扇门小,那么这扇门也比第二扇门小,你继续打开这扇门,一直这样继续下去直到打开所有的门。但是,入口处的人始终等不到你回去告诉他答案。
我们再通过对n的阶乘的循环表示和递归表示:
循环:

int factor=1;
while(n){
factor*=n;
n--;
}
 

递归:

int Factor(n)
{
if(n==1)
  return 1;
else 
  return n*Factor(n-1);

明显区别:递归是需要不断地调用自身,调用自身函数所花费的开销相较于循环是巨大的(循环不需要函数调用),所以在选择时,需要考虑花销的情况下,优先考虑循环。

用递归的方式来实现汉诺塔
代码:

#include<iostream>
using namespace std;
void harro(int X,char a,char b,char c);
void move_one(int n,char a,char b);
  extern  int  num=0;

int main (){
 int n;

cout<<"请输入汉诺塔层数:"<<endl;
cin>>n;
 harro(n,'A','B','C');
 cout<<"一共为:"<<num<<"步"<<endl;
return 0;
}
void harro(int n,char a,char b,char c){

    if(n==1) move_one(n,a,c);
    else {
       harro(n-1,a,c,b);
       move_one(n,a,c);
       harro(n-1,b,a,c);
    }

}
void move_one(int n,char a, char b){

  cout<<n<<"个将"<<a<<"移到"<<b<<endl;
  num++;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值