算法大总结之一:递归算法!

 上课,同学们好!

今天开始,我将讲解算法大总结。那么让我们开始吧。首先,我今天要讲的是:递归算法。

我觉得讲课要讲得透彻,必须让学生知其所以然。所以,我第一要讲的是:为什么需要递归算法?

让我们看下面这个数学式子:f(n)=f(n-1)+f(n-2),f(0)=0,f(1)=1;
非常明显,若我们想求出f(N),如果不使用递归,那么就必须使用烦琐的嵌套for语句,更要命的是,当N→∞时,for语句将会变成程序的瓶颈,因为它需要大量时间计算!!最终很可能无法“得到”答案。
如果使用递归,那么,程序在时间上的开销将大大降低,当然,其内存消耗会比前面的嵌套for语句要多。
在时间、内存权衡情况下,我们往往宁愿多牺牲内存,毕竟,扩充内存总比等待很长(有时甚至无法“解出”答案)时间才得出答案要好!

那么,我们如何写递归算法呢?

拿上面所提到的数学式子来说,其递归算法是这么写出的:
long function(int N)
{
if(N==0) return 0;
   if(N==1) return 1;
      if(N>1)
         return (function(N-1)+function(N-2));
  return -1;
}

看上去很简单,不过却包含了写递归算法的准则:
1,必须要有基本条件;
2,程序必须朝基本条件运行。

f(n)=f(n-1)+f(n-2)必须要有基本条件,否则将无从算起,这个基本条件就是:f(0)=0,f(1)=1。这一点,基本上初学者不会犯错。

第二点,是最容易犯错误的:程序必须朝基本条件运行!试看下面这个程序:
int Bad(unsigned int N)

{

            if(N==0)

             return 0;

          else return Bad(N/3+1)+N-1;

}
该程序摘自Mark Allen Weiss 的《Data structures and algorithm analaysis in C》。
是的,它有基本条件,可是,它会朝着这个基本条件运行吗?计算Bad(1)试试看,很明显
Bad(N/3+1)+N-1=Bad(1)+0 !!!
也就是说,这个程序若是要计算Bad(1)那么它将会原地踏步!由于Bad(1)无法计算出来,那么Bad(2)、Bad(3)……都无法计算出来!!

因此,我们为了注意不要犯这个错误,我们引入第三个准则:
3,每次递归调用,都必须向基本条件前进。
很明显,如果调用的就是基本条件时的情况,那么我们不应该再递归了,因此有第四个准则:
4,如果结果已知,那么,不用再重复调用递归。
3、4条准则似乎很多余,但是它却是提醒我们不要犯在写递归调用程序时容易犯的错误。

递归的应用
递归有什么用呢?其实,递归并不是个好算法,因为在有多次(实际情况很可能是许多许多次)调用递归的情况下,会非常耗内存。因此,我们使用递归算法,必须权衡运行时间与内存这两者的消耗,一般来说,递归算法不适合解决数学计算!当然,我们以后会讲到更好的算法,使得运行时间与内存都比较少的情况下解决问题!

具体来说,一般递归用于关于二叉树的算法。
以下程序是关于构造、遍历二叉树的,其中使用了递归算法:
#include<stdio.h>
typedef struct node * tree;
struct node
{
int number;
tree left;
tree right;
};

tree createTree();
void travelTree(tree );

int main()
{
tree root;
root=createTree();
travelTree(root);
getch();
return 0;
}

tree createTree()
{
int n;
tree root;
root=(tree)malloc(sizeof(struct node));
if(root==NULL) exit(1);
printf("intput a number :");
scanf("%d",&n);
if(n==-1)
{
  return NULL;
}
else
{
  root->number=n;
  root->left=createTree();
  root->right=createTree();;
}
return root;
}

void travelTree(tree r)
{
if(r!=NULL)
{
  printf("%d  ",r->number);
  travelTree(r->left);
  travelTree(r->right);//此处按先序遍历
}
}

同学们,看得懂吗?OK,不懂的下课问!
今天的课就讲到这里,下课!
下次课我讲最常用的五种算法之一:贪心算法,并且用它来解决实际问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值