C语言中递归函数的设计

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

从前有座山,山上有个庙,庙里有个老和尚 和3岁的小和尚,老和尚给小和尚讲故事,讲的是: 从前有座山,山上有个庙,庙里有个老和尚和2岁 的小和尚,老和尚给小和尚讲故事,讲得是:从 前有座山,山上有个庙,庙里有个老和尚和1岁的 小和尚. 这里的递归结束条件即小和尚的年龄,因为 没有0岁的小和尚,所以讲到"庙里有个老和尚和 l岁的小和尚"时,故事结束.每次递归都使小和 尚的年龄减少一岁,所以总有终止递归的时候, 不会产生无限递归.
前面我们把递归问题分为两大类:数值问题和非 数值问题.这两类问题具有不同的性质,所以解 决问题的方法也不同. 对于数值问题,由于可以表达为数学公式, 对于数值问题 所以可以从数学公式入手推导出问题的递归定义, 然后确定问题的边界条件,从而确定递归的算法 和递归结束条件. 对于非数值问题,其本身难以用数学公式表 对于非数值问题 达.求解非数值问题的一般方法是要设计一种算 法,找到解决问题的一系列操作步骤.如果能够 找到解决问题的一系列递归操作步骤,同样可以 用递归的方法解决这些非数值问题,寻找非数值 问题的递归算法可以从分析问题本身的规律入手, 可以按照下列步骤进行分析:
新课导入:C程序结构是函数模块结构,C程序是 由一个或多个函数构成的,是函数的集合.函 数具有相对独立的特定功能,是程序的基本单 位,因此,在C语言教学中,函数这一章(大部 分教材把函数作为一章)是重点内容,而函数的 递归调用则是这一章的重点之一.下面我们首 先来看递归函数的定义
一,递归的定义
在调用一个函数的过程中调用该函数本身,称 为函数的递归调用.递归调用简称递归.
#include<stdio.h> void main() { int gcd(int m,int n); int m,n,g; printf("请输入整数m,n:"); scanf("%d%d",&m,&n); printf("\n"); g=gcd(m,n); printf("%d和%d的最大公约数是:%d\n",m,n,g); } int gcd(int m,int n) { int g; if(n==0) g=m; else g=gcd(n,m%n); return g; }
#include<stdio.h> void main() { void movedisk(int n,char fromneedle,char tempneedle,char toneedle); int n; printf ("Pleases input the number of diskes:"); scanf("%d",&n); printf源自文库("The step moving diskes is:\n"); movedisk (n,'A','B','C'); } void movedisk(int n,char fromneedle,char tempneedle,char toneedle) { if (n==1) printf ("%c %c\n",fromneedle,toneedle ); else { movedisk(n-1,fromneedle,toneedle,tempneedle ); printf ("%c %c\n",fromneedle,toneedle ); movedisk (n-1,tempneedle,fromneedle,toneedle ); } }
C语言中递归函数的设计 语言中递归函数的设计
主讲人 熊立伟 (武汉大学 遥感信息工程学院)
1,教学目标 使学生学会使用和设计递归函数去解决较复杂 的问题 2,教学重点 递归函数的定义,递归问题的分类,递归函数 设计的一般步骤 3,教学难点 理解递归函数的内涵,确定递归结束条件 4,教学方法 讲故事激发学生兴趣,巧解概念,典型例题分 析
三,典型例题分析
首先来看一个数值问题的递归算法
例1用辗转相除法求整数m与n的最大公约数. 讨论:此问题属于数值问题,求m与n的最大 公约数等价于求n与(m%n)的最大公约数,这时可 以把n当作新的m,(m%n)当作新的n,问题变成了 求新的m与新的n的最大公约数,它又等价于求新 的n与(m %n)的最大公约数……如此继续,直到 新的n=0时,所求最大公约数就是新的m,这就是 用辗转相除法求m与n的最大公约数的过程. 因此,有如下递归算法: 1.求r=m%n 2.若r=0,则n为所求,输出n,结束 3.若r!=0,则令m=n,n=r 4.转向步骤1 按照上述算法可编写出如下C语言程序:
第一步,将问题进行化简,将问题的规模缩到 第一步 最小,分析问题在最简单情况下的求解方法, 这时的算法应当是最简单的非递归算法. 第二步,将问题分解为若干个小问题,其中至 第二步 少有一个小问题具有与原问题相同的性质,只 是在规模上比原问题有所缩小,将分解后的每 个小问题作为一个整体,描述用这些较小的问 题解决原来较大问题的算法. 由第二步得到的算法就是一个解决原问题的递 归算法,第一步将问题的规模缩到最小时的条 件就是该递归算法的结束条件.
不难计算,对于n个盘子需要移动2n -1次,把64个 盘子都移动完毕约需1.8X1019次,假设每秒移动 一次,约需一万亿年,若用现代电子计算机计算, 设一微秒可计算(并不输出)一次移动,也几乎需 要一百万年.目前,由于计算机运算速度的限制, 我们仅能找出问题的解决方法并解决较小n值的汉 诺塔问题. 讨论:汉诺塔问题属于非数值问题,难以用 数学公式表达其算法,可以从分析问题本身的规 律入手. 第一步,问题化简,设A针上只有一个盘子, 即n=1,则只需将1号盘从A针移到C针. 第二步,问题分解,对于有n(n>1)个盘子 的汉诺塔,可分为三个步骤求解:
五,总结
递归是一个十分有用的方法.当一个问题 蕴含了递归关系且结构比较复杂时,采用递归 调用的程序设计技巧可以使程序变得简洁,增 加了程序的可读性,递归调用能使代码紧凑, 并能够很容易地解决一些用非递归法很难解决 的问题. 当然,递归算法也有它的缺点,递归程序 通常要花费较多的机器时间和占用较多的存储 空间,另外也不是每个问题都适合用递归方法 求解.
有这么一个古老的故事:从前有座山,山上 有个庙,庙里有个老和尚和小和尚,老和尚给小 和尚讲故事,讲的是:从前有座山,山上有个庙, 庙里有个老和尚和小和尚,老和尚给小和尚讲故 事,讲的是…… 这是一个典型的"递归"故事,可以无限次 递归下去.当大人们肚中无故事而又要哄小孩时, 常常讲这个故事. 我们可把这个故事比喻成递归调用,但在C 语言程序设计中,程序不可无限地递归下去,必 须有递归结束条件,而且每次递归都应该向结束 条件迈进,直到满足结束条件而停止递归调用. 为此,可将上述"递归"故事修改如下:

movedisk(int n,char fromneedle,char tempneedle,char toneedle) { if (n==1) 将n号盘子从one针移到three针; esle 1. movedisk(n-1 , fromneedle , toneedle , tempneedle) 2.将n号盘子从fromneedle针移到toneedle针; 3. movedisk(n-1, tempneedle, fromneedle, toneedle) } 按照上述算法可编写出如下C语言程序:
二,递归的分类
1,数值问题 可以表达为数学公式的问题,如求非负整数N 的阶乘,求斐波那契数列的第n项,求两个整 数的最大公约数等. 2,非数值问题 其本身难以用数学公式表达的问题,如著名的 汉诺塔问题,八皇后问题.
三,递归函数设计的一般步骤
编写递归程序有两个要点:一是要找到正确的 一是要找到正确的 递归算法,这是编写递归程序的基础; 递归算法,这是编写递归程序的基础;二是要 确定递归算法的结束条件, 确定递归算法的结束条件,这是决定递归程序 能否正常结束的关键. 能否正常结束的关键.
1.将A针上n-1个盘子借助于C针移到B针 2.把A针上剩下的一个盘子移到C针 3.将B针上n-1个盘子借助于A针移到C针 显然,上述1,3两步具有与原问题相同的性质, 只是在问题的规模上比原问题有所缩小,可用递 归实现. 整理上述分析结果,把第一步作为递归结束 条件,将第二步分析得到的算法作为递归算法, 可以写出如下完整的递归算法描述: 定义一个函数movedisk (int n,char fromneedle ,char tempneedle , char toneedle ), 该函数的功能是将fromneedle针上的n个盘子借助 于tempneedle针移动到toneedlee针,这样移动n 个盘子的递归算法描述如下:
下面我们再来看一个非数值问题的递归算法 例2汉诺塔(Hanoit)问题 这是一个著名的问题,相传在很久很久以前, 在中东地区的一个寺庙里,几个和尚整天不停地 移动着盘子,日复一日,年复一年,移盘不止, 移动盘子的规则是这样的:事先固定三根针,假 设分别为A针,B针,C针,A针上套有64个中间 带孔的盘子,盘子大小不等,大的在下,小的在 上,要求把这64个盘子从A针移到C针,在移动过 程中可以借助于B针,每次只允许移动一个盘子, 且移动过程中的每一步都必须保证在三根针上都 是大盘在下,小盘在上.据说当所有64个盘子全 部移完的那一天就是世界的末日,故汉诺塔问题 又被称为"世界末日问题".
相关文档
最新文档