递归算法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3
二、在数学与计算机科学中,递归是指在函数 的定义中使用函数自身的方法。
例:阶乘的定义。
当n 0时 1 n! n (n 1) ...1 当n 0时
4
在下面二种情况中存在算法调用自己的情况:
(1)问题的定义是递推的 阶乘函数的常见定义是:
当n 0时 1 n! n (n 1) ...1 当n 0时
11
递归算法如下:
int BSearch(int a[], int x, int low, int high) { int mid; if(low > high) return -1; //查找不成功 mid = (low + high) / 2; if(x == a[mid]) return mid; //查找成功 else if(x < a[mid]) return BSearch(a, x, low, mid-1);//在下半区查找 else return BSearch(a, x, mid+1, high);//在上半区查找 }
3.1递归的概念
一、在日常生活中,递归一词较常用于描述以 自相似方法重复事物的过程。
例如,当两面镜子相互之间近似平行时,镜
中嵌套的图像是以无限递归的形式出现的。
2
德罗斯特效应(英语:
Droste effect)是递归的一 种视觉形式。图中女性手持 的物体中有一幅她本人手持 同一物体的小图片,进而小 图片中还有更小的一幅她手 持同一物体的图片,依此类 推。
第一次: 下标 元素值 0 1 ↑ low 第二次: 下标 元素值 0 1 1 3 2 4 1 3 2 4 3 5 ↑ mid 3 5 4 17 ↑ low 第三次: 下标 元素值 0 1 1 3 2 4 3 5 4 17 ↑ low 5 18 ↑ mid 5 18 6 31 6 31 4 17 5 18 6 31 7 33 ↑ high 7 33 ↑ high 7 33 x<a[mid] x>a[mid]
13
BSearch(a, x, 0,7)的递归调用过程如下图所示,其 中,实箭头表示过程调用,虚箭头表示过程的返回值。
BSearch(a, x, 0, 7)
…
mid=3 main() … x=17 … bn = BSearch(a, x, 0, 7) … BSearch(a, x, 4, 4) … mid=4 … BSearch(a, x, 4, 7) … mid=5 return 4
12
测试代码设计如下:
# include <stdio.h> main(void) { int a[] = {1, 3, 4, 5, 17, 18, 31, 33}; int x = 17; int bn; bn = BSearch(a, x, 0,7); if(bn == -1) printf("x不在数组a中"); else printf("x在数组a的下标%d中", bn); }
9
Hale Waihona Puke Baidu
递归调用的执行过程:
main() …… fn=Fact(3) ……
Fact (2) …… y=Fact(1) …… return 2*y
Fact (0) …… …… return 1
Fact (3) …… y=Fact (2) …… return 3*y
Fact (1) …… y=Fact(0) …… return 1*y
10
例3-2 给出在有序数组a中查找数据元素x 是否存在的递归算法,并给出折半查找示意图 所示实际数据的递归算法的执行过程。 设计:算法的参数包括:有序数组a,要查 找的数据元素x,数组下界下标low,数组上界 下标high。当在数组a中查找到数据元素x时函 数返回数组a的下标;当在数组a中查找不到数 据元素x时函数返回-1。
4
return BSearch(a, x, 4, 7)
4 4
…
return BSearch(a, x, 4, 4)
14
3.3递归算法的设计方法
递归算法既是一种有效的算法设计方法,也 是一种有效的分析问题的方法。递归算法求解 问题的基本思想是:对于一个较为复杂的问题, 把原问题分解成若干个相对简单且类同的子问 题,这样较为复杂的原问题就变成了相对简单 的子问题;而简单到一定程度的子问题可以直 接求解;这样,原问题就可递推得到解。
8
为说明该递归算法的执行过程,设计调用过程如下:
void main(void) { long int fn; fn = Fact(3); } 上述代码用实参n = 3调用了递归算法Fact(3),而 Fact(3)要通过调用Fact(2)、Fact(2)要通过调用Fact(1)、 Fact(1)要通过调用Fact(0)来得出计算结果。Fact(3)的递 归调用过程如下图所示,其中,黑色实线箭头表示函数调 用,绿色虚线箭头表示函数返回,此函数在返回时函数名 将带回返回值。
5
也可定义为:
当n 0时 1 n! n (n 1)! 当n 0时
写成函数形式,则为:
当n 0时 1 f (n) n * f (n 1) 当n 0时
这种函数定义的方法是用阶乘函数自己本身定义了 阶乘函数,称上式为阶乘函数的递推定义式。
6
(2)问题的解法存在自调用 一个典型的例子是在有序数组中查找一个数据元素是否存 在的折半查找算法。 如下例中查找元素17。
mid=(low+high)/2
high
mid
x=a[mid]
BSrch=4
7
3.2递归算法的执行过程
例3-1 给出按照阶乘函数的递推定义式计算阶乘函数的递 归算法,并给出n = 3时递归算法的执行过程。 设计:按照阶乘函数的递推定义式计算阶乘函数的递归算 法如下:
long int Fact(int n) { int x; long int y; if(n < 0) //n < 0时阶乘无定义 { printf(“参数错!”); return -1; } if(n == 0) return 1; else { y = Fact(n - 1); //递归调用 return n * y; } }