数据结构(递归及应用)

递归是数据结构中一种常用的算法,在非线性结构中,有相当多的问题都是使用递归的方法来解决,递归也是一种“很好用”的方法。

那么什么是递归呢?

递归就是将一个复杂的问题化成若干个简单的小问题,通过解决若干个小问题,在解决这整个大问题。通过函数自我调用过程(一个函数中使用“另一个函数”,那个函数就是自己本身的函数)先解决小问题中的“小问题”然后在解决整个小问题,最后解决整个大问题。小编对递归的理解是,先将一个大问题分成若干的小问题,在依次将若干个小问题继续分解成更“小”的问题,找到一个不能分解的最“小”的问题,并解决,最后依次解决各种小问题,最后解决大问题,这就是递归的全过程。

上面的讲述可能不太理解,那我们通过有关例子来解决。我们以最经典的递归例题,斐波那契数列为例。就是兔子数列。以a1为数列的首元素,已知第n个元素是第n-1个元素和第n-2个元素之和,而第一个和第二个元素为1。那我们如何求出第n个元素呢?

按照我们上面的说法,将“求出第n个元素看成是一个复杂的大问题”,我们将这大问题分解成两个小问题,分别是求出an-1和an-2,求出第an-1和an-2之后,就可以求出an,那我们又如何求出an-1和an-2呢?同样,将这两个小问题分解成跟小的问题,直到找出“最小的问题”,而这个最小的问题就是求出a1和a2。代码实现如下:

#include <stdio.h>

int ff(int n)           //我们要求求出第n个元素
{
    if(n==1||n==2)      //如果n为1或者n为2这返回值为1;
        return 1;
    else                //否则我们将问题分解,分解成两个小问题。调用自身函数来解决这些问题
        return ff(n-1)+ff(n-2);
}

一些刚接触c语言的新手可能不容易看懂,我们使用图片来解决

如图,如果n为5,将求出a5分成求出a4和a3两个小问题,再将求出a4分成求出a3和a2两个小问题,在将求出a3分成求出a1和a2两个小问题,由于a1和a2等于1,我们就可以解决求出a4这个小问题,同理,在解决求出a3这个小问题,我们就解决求出a5这个大问题。

那么递归的结构如何设计呢?

首先,递归的结构有两个最重要的因素,递归体和递归出口。递归体就是分解问题的部分,将大问题分解成两个小问题,而递归出口就是定义最“小”的问题,最后解决最小的问题。递归出口不等于整个递归的结束,而是整个递归体的结束,整个递归体结束后在依次解决一些小问题,最后解决大问题,就算整个递归结束。

我们重新换一个结构为例来讲解,以求n的阶层来讲解:

首先n的阶层的定义就是从1开始一直乘到n,(1*2*3*4.......*n)若我们要求出n的阶层,将这个大问题化成一个小问题,就是先算出n-1的阶层,而要算出n-1的阶层就要先算出n-2的阶层。依次递归。而递归出口就是n为1的时候。代码实现如下。

#include <stdio.h>

int f1(int n)
{
     if(n==1)
         return 1;       //递归出口
     else
         return n*f(n-1);//递归体
}

 递归体相当于函数的自我调用过程,也是分解问题的过程。

递归在二叉树和一些算法中有着重要的应用,首先要理解递归,先要理解函数的自我调用。

这里留给大家几个问题:

1.递归有没有可能进入一个死循环

2.如何寻找递归出口和递归体

3.对于汉诺塔问题如何使用递归来解决。

递归的定义已经讲解完成,谢谢您的阅读。若有不足或者错误之处,欢迎在评论区指出,谢谢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值