2 2 递归与非递归程序的转换
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
using namespace std;
int result=0; for(int i=x; i>0; i--)
result+=x;
int _tmain(int argc, _TCHAR* argv[]) return result;
{
cout<<sum(5000);
}
return 0;
}
2 为什么:递归非递归?
fun(2)=2
d4:fun(1)
返回 1
1 递归算法的设计
斐波 那契 数: 一个 大问 题分 解为 多个 小问 题的 过程
1 递归算法的设计
算法设计:先将整个问题划分为若干个子问题, 通过分别求解子问题,最后获得整个问题的解。
– 而这些子问题具有与原问题相同的求解方法,于是可 以再将它们划分成若干个子问题,分别求解,如此反 复进行,直到不能再划分成子问题,或已经可以求解 为止。
– (3)确定一个特定情况(如f(1)或f(0))的解,由此作为递 归出口(与数学归纳法中求证n=1时等式成立相似)。
1 递归算法的设计
课堂练习:
– 采用递归算法求实数数组A[0..n-1]中的最小值。
– 基本步骤:
先定义清楚问题; 写出递归模型; 转换为算法。
2 为什么:递归非递归?
递归程序非递归程序
张仕 shi@fjnu.edu.cn
0 递归的基本概念
递归:在定义一个过程或函数时,如果出现调 用本过程或本函数的成分,则称为递归。
直接递归:在定义一个过程或函数时,出现直 接调用本过程或本函数成分的情况。
直接递归:在定义一个过程或函数时,出现间 接调用本过程或本函数成分的情况。
– 但递归分解不是随意的分解,递归分解要保证“大 问题”与“小问题”相似,即求解过程与环境都相 似。并且有一个分解的终点。从而使问题可解。
1 递归算法的设计
逐步分 解和组 合求值 的过程
fun(5)
fun(5)=120
d1:fun(4)
fun(4)=24
d2:fun(3)
fun(3)=6
d3:fun(2)
if(x<=0) return 0; return x+add(x-1); }
int _tmain(int argc, _TCHAR* argv[]) {
cout<<add(5000); return 0; }
2 为什么:递归非递归?
利用非递归(迭代)求该函数
int sum(int x)
{
#include "stdafx.h" #include <iostream>
1 递归算法的设计
一般地,一个递归模型是由递归出口和递归体 两部分组成, 前者确定递归到何时结束, 后者确 定递归求解时的递推关系。
– 递归出口的一般格式如下: – f(s1)=m1 – 这里的s1与m1均为常量,有些递归问题可能有几个
递归出口。
1 递归算法的设计
递归体的一般格式如下:
– f(sn+1)=g(f(si),f(si+1),…,f(sn),cj,cj+1,…,cm) – 其中,
– n,i,j,m均为正整数。
–
sn+1是一个递归“大问题”,
–
si,si+1,…,sn为递归“小问题”,
–
cj,cj+1,…,cm是可以用非递归方法直接解决的问题
– g是一个非递归函数,可以直接求值。
1 递归算法的设计
递归思路
– 实际上,递归思路是把一个不能或不好直接求解的 “大问题”转化成一个或几个“小问题”来解决, 再把这些“小问题”进一步分解成更小的“小问题” 来解决,如此分解,直至每个“小问题”都可以直 接解决(此时分解到递归出口)。
– 问题求解的方法是递归的。例如汉诺塔问题,其求 解方法是递归的。
1 递归算法的设计
递归模型:递归模型是递归算法的抽象,它反 映递归问题的递归结构,例如,前面的递归算法 对应的递归模型如下:
– fun(0)=1
n=0 (1)
fun(n)=n*fun(n-1)
n>0 (2)
– 其中:第一个式子给出了递归的终止条件,我们称 之为递归出口;第二个式子给出了fun(n)的值与 fun(n-1)的值之间的关系,我们称之为递归体。
了什么功能?
{ return X*function_2(X-
还有哪些常见的递归函数? 1);
}
0 递归的基本概念
在什么情况下用到递归方法
– 给出的定义是递归的:许多数学公式、数列的定义 是递归的,这是可以直接把递归定义转换为递归算 法:例如Fabonacci数列。
– 数据结构是递归的:常见的有树、链表等数据结构 的定义。对于这类数据结构,常采用递归的方法进 行操作。例如链表的遍历、树的遍历操作。
引例
– 求如下函数值
Sum(1..X)=X+Sum(1..X-1) X>0
Sum(1..X)=0
X<=0
它的程序?
2 为什么:递归非递归?
利用递归求该函数
#include "stdafx.h" #include <iostream> using namespace std;
int add(int x) {
0 递归的基本概念
function_1(X)
function_2(X)
{ if( X) X*function_1(X-1); else return;
}
{ if( X) function_3(X); else return;
}
Function_1、function_2实现 function_3(X)
– 这种自上而下将问题分解、求解,再自上而下引用、 合并,求出最后解答的过程称为递归求解过程。
– 这是一种分而治之的算法设计方法。
1 递归算Baidu Nhomakorabea的设计
递归设计的步骤如下:
– (1)对原问题f(s)进行分析,假设出合理的“较小问 题”f(s')(与数学归纳法中假设n=k-1时等式成立相 似);
– (2)假设f(s')是可解的,在此基础上确定f(s)的解,即给 出f(s)与f(s')之间的关系(与数学归纳法中求证n=k时 等式成立的过程相似);
它们的运行结果? 递归
– X=10 – X=100 – X=1000 – X=10000 – X=100000 –… …
为什么?
迭代
2 为什么:递归非递归?
利用递归求该函数
int add(int x)
{
#include "stdafx.h" #include <iostream>
int result=0; for(int i=x; i>0; i--)
result+=x;
int _tmain(int argc, _TCHAR* argv[]) return result;
{
cout<<sum(5000);
}
return 0;
}
2 为什么:递归非递归?
fun(2)=2
d4:fun(1)
返回 1
1 递归算法的设计
斐波 那契 数: 一个 大问 题分 解为 多个 小问 题的 过程
1 递归算法的设计
算法设计:先将整个问题划分为若干个子问题, 通过分别求解子问题,最后获得整个问题的解。
– 而这些子问题具有与原问题相同的求解方法,于是可 以再将它们划分成若干个子问题,分别求解,如此反 复进行,直到不能再划分成子问题,或已经可以求解 为止。
– (3)确定一个特定情况(如f(1)或f(0))的解,由此作为递 归出口(与数学归纳法中求证n=1时等式成立相似)。
1 递归算法的设计
课堂练习:
– 采用递归算法求实数数组A[0..n-1]中的最小值。
– 基本步骤:
先定义清楚问题; 写出递归模型; 转换为算法。
2 为什么:递归非递归?
递归程序非递归程序
张仕 shi@fjnu.edu.cn
0 递归的基本概念
递归:在定义一个过程或函数时,如果出现调 用本过程或本函数的成分,则称为递归。
直接递归:在定义一个过程或函数时,出现直 接调用本过程或本函数成分的情况。
直接递归:在定义一个过程或函数时,出现间 接调用本过程或本函数成分的情况。
– 但递归分解不是随意的分解,递归分解要保证“大 问题”与“小问题”相似,即求解过程与环境都相 似。并且有一个分解的终点。从而使问题可解。
1 递归算法的设计
逐步分 解和组 合求值 的过程
fun(5)
fun(5)=120
d1:fun(4)
fun(4)=24
d2:fun(3)
fun(3)=6
d3:fun(2)
if(x<=0) return 0; return x+add(x-1); }
int _tmain(int argc, _TCHAR* argv[]) {
cout<<add(5000); return 0; }
2 为什么:递归非递归?
利用非递归(迭代)求该函数
int sum(int x)
{
#include "stdafx.h" #include <iostream>
1 递归算法的设计
一般地,一个递归模型是由递归出口和递归体 两部分组成, 前者确定递归到何时结束, 后者确 定递归求解时的递推关系。
– 递归出口的一般格式如下: – f(s1)=m1 – 这里的s1与m1均为常量,有些递归问题可能有几个
递归出口。
1 递归算法的设计
递归体的一般格式如下:
– f(sn+1)=g(f(si),f(si+1),…,f(sn),cj,cj+1,…,cm) – 其中,
– n,i,j,m均为正整数。
–
sn+1是一个递归“大问题”,
–
si,si+1,…,sn为递归“小问题”,
–
cj,cj+1,…,cm是可以用非递归方法直接解决的问题
– g是一个非递归函数,可以直接求值。
1 递归算法的设计
递归思路
– 实际上,递归思路是把一个不能或不好直接求解的 “大问题”转化成一个或几个“小问题”来解决, 再把这些“小问题”进一步分解成更小的“小问题” 来解决,如此分解,直至每个“小问题”都可以直 接解决(此时分解到递归出口)。
– 问题求解的方法是递归的。例如汉诺塔问题,其求 解方法是递归的。
1 递归算法的设计
递归模型:递归模型是递归算法的抽象,它反 映递归问题的递归结构,例如,前面的递归算法 对应的递归模型如下:
– fun(0)=1
n=0 (1)
fun(n)=n*fun(n-1)
n>0 (2)
– 其中:第一个式子给出了递归的终止条件,我们称 之为递归出口;第二个式子给出了fun(n)的值与 fun(n-1)的值之间的关系,我们称之为递归体。
了什么功能?
{ return X*function_2(X-
还有哪些常见的递归函数? 1);
}
0 递归的基本概念
在什么情况下用到递归方法
– 给出的定义是递归的:许多数学公式、数列的定义 是递归的,这是可以直接把递归定义转换为递归算 法:例如Fabonacci数列。
– 数据结构是递归的:常见的有树、链表等数据结构 的定义。对于这类数据结构,常采用递归的方法进 行操作。例如链表的遍历、树的遍历操作。
引例
– 求如下函数值
Sum(1..X)=X+Sum(1..X-1) X>0
Sum(1..X)=0
X<=0
它的程序?
2 为什么:递归非递归?
利用递归求该函数
#include "stdafx.h" #include <iostream> using namespace std;
int add(int x) {
0 递归的基本概念
function_1(X)
function_2(X)
{ if( X) X*function_1(X-1); else return;
}
{ if( X) function_3(X); else return;
}
Function_1、function_2实现 function_3(X)
– 这种自上而下将问题分解、求解,再自上而下引用、 合并,求出最后解答的过程称为递归求解过程。
– 这是一种分而治之的算法设计方法。
1 递归算Baidu Nhomakorabea的设计
递归设计的步骤如下:
– (1)对原问题f(s)进行分析,假设出合理的“较小问 题”f(s')(与数学归纳法中假设n=k-1时等式成立相 似);
– (2)假设f(s')是可解的,在此基础上确定f(s)的解,即给 出f(s)与f(s')之间的关系(与数学归纳法中求证n=k时 等式成立的过程相似);
它们的运行结果? 递归
– X=10 – X=100 – X=1000 – X=10000 – X=100000 –… …
为什么?
迭代
2 为什么:递归非递归?
利用递归求该函数
int add(int x)
{
#include "stdafx.h" #include <iostream>