您的位置:首页 > 其它

递归,栈的重要应用之一

2012-08-04 00:00 1131 查看
栈有一个很重要的应用:在程序设计语言中实现了递归。那么什么是递归呢?

当你往镜子前面一站,镜子里面就有一个你的像。但你试过两面镜子一起照吗?如果A、B两面镜子相互面对面放着,你往中间一站,嘿,两面镜子里都有你的千百个 “化身”。为什么会有这么奇妙的现象呢?原来,A镜子里有B镜子的像,B镜子里也 有A镜子的像,这样反反复复,就会产生一连串的“像中像” 这是一种递归现象。

我们先来看一个经典的递归例子:斐波那契数列(Fibonacci)。为了说明这个数列,这位斐老还举了一个很形象的例子。

斐波那契数列

如果兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子 来。假设所有兔都不死,那么一年以后可以繁殖多少对兔子呢?

我们拿新出生的一对小兔子分析一下:第一个月小兔子没有繁殖能力,所以还是一对;两个月后,生下一对小兔子数共有两对;三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,所以一共是三对……依次类推。

经过月数123456789101112
兔子对数1123581321345589144
表中数字1, 1,2,3, 5, 8,13……构成了一个序列。这个数列有个十分明显的 特点,那是:前面相邻两项之和,构成了后一项。

算法的可以描述为:

def Fib(n):
if (n
假设我们不了解递归,我们要实现这样的数列用常规的的办法如何实现?

比如我们需要打印出前20位的斐波那契数列数。


先定义一个数组a,能存20个数。然后赋值a[0]=0,a[1]=1,然后根据它们的和凑第三个数。往后的数都是通过前两个数凑出来,a[i] = a[i-1] + a[i-2]; 这是常规的思路。

#include "stdio.h"
int main()
{
int i;
int a[20];
printf("迭代显示斐波那契数列:\n");
a[0]=0;
a[1]=1;
printf("%d ",a[0]);
printf("%d ",a[1]);
for(i = 2;i
程序运行结果为:

迭代显示斐波那契数列:
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181



嗯,代码很简单,几乎不用做什么解释。但其实我们的代码,如果用递归来实现,还可以更简单。

#include "stdio.h"
int Fbi(int i)  /* 斐波那契的递归函数 */
{
if( i
怎么样,相比较迭代的代码,是不是干净很多。嘿嘿,不过要弄懂它得费点脑子。

函数怎么可以自己调用自己?听起来有些难以理解,不过你可以不要把一个递归函数中调用自己的函数看作是在调用自已,而就当它是在调另一个函数。只不过,这个函数和自己长得一样而已。我们来模拟代码中的Fbi(i)函数当i = 5的执行过程,如下图。



或者看看另外一种描述:


延伸阅读

此文章所在专题列表如下: 栈的定义与大概理解 栈的抽象数据类型ADT 顺序栈:栈的顺序存储结构 顺序栈的进栈操作 顺序栈的出栈操作 获取顺序栈的栈顶元素 链栈:栈的链式存储结构 链栈的进栈操作 链栈的初始化与遍历 链栈的出栈操作 链栈的置空操作与判断链栈是否为空 为什么要使用栈这种数据结构 递归,栈的重要应用之一 栈是如何实现递归的 接触后缀表达式(逆波兰表示法) 图解后缀表达式的计算过程 将中缀表达式转化为后缀表达式 开始学习队列这个数据结构 队列的抽象数据类型ADT 顺序队列:队列的顺序存储结构 顺序队列的入队操作 顺序队列的出队操作 顺序队列置空与判断操作 队列顺序存储结构的不足 关于循环队列的一些讲解 链队列:队列的链式存储结构 链队列的初始化操作 链队列的入队操作 链队列的出队操作 补完链队列的其它常见操作 循环队列与链队列的优劣势 本文地址:http://www.nowamagic.net/librarys/veda/detail/2298,欢迎访问原出处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: