递归与分治相关实验及代码

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

实验目的:

掌握递归与分治算法的基本原理和应用以及软件实现。

实验准备:

1.在开始本实验之前,请回顾教科书的相关内容;

2.需要一台准备安装Windows XP Professional操作系统和装有VC++6.0的计算机。

实验内容及要求

内容:完成递归与分治常见实例的实现。

要求:

1,熟悉C++的相关语法和编制独立的子程序。

2,输入多组数据都能够给出正确的结果。

实验过程:

1.1问题分析

递归算法是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。一般通过函数或子过程来实现,在函数或子过程的内部,直接或者间接地调用自己的算法。该算法具有以下特点:(1) 递归就是在过程或函数里调用自身。(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。该算法所体现的“重复”一般有三个要求:一是每次调用在规模上都有缩减;

二是相邻两次重复之间有紧密的联系,前一次要为后一次做准备;

三是在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归调用将会成为死循环而不能正常结束。

通常该算法的时间复杂度很大,所以要在适当的条件下使用。在该实验中,采用递归算法得到的算法有:阶乘,斐波拉齐,数的排列等。

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同,求出子问题的解,就可得到原问题的解。利用分治策略求解时,所需时间取决于分解后子问题的个数、子问题的规模大小等因素,而二分法,由于其划分的简单和均匀的特点,是经常采用的一种有效的方法,例如二分法检索。分治法解题的一般步骤:

(1)分解,将要解决的问题划分成若干个规模较小的同类问题;

(2)求解,当子问题划分得足够小时,用较简单的方法解决;

(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。

在该实验中,使用分治算法得到的程序有棋盘覆盖、二分法检索、合并排序、快速排序、循环赛日程表。

1.2 核心代码 1、阶乘

阶乘函数的递归的定义是 10

!(1)!0

n n n n n =⎧=⎨->⎩,从定义可知,递归的出口时当n==0时,程序结束。

程序如下:

#include using namespace std; int jiecheng(int n) {

if (n==0) return 1; if(n>0) {return n*jiecheng(n-1);} }

int main() {

int m,a; cin>>m;

a=jiecheng(m);cout<

}

从得到的实验数据分析,该数据只能针对数据较小的数成立,如果将数据定义为整数型,则只能计算20以下的数的阶乘,如果将数定义为100或者1000以上,则需要根据大数定理来做此问题。相对来说比较复杂,在此就不做讨论。

2、斐波拉齐

若有无穷数列1,1,2,3,5,8,13,21,34,55,…,则被称为Fibonacci 数列。它可以递归地定义为:

10()11(1)(2)1n F n n F n F n n =⎧

⎪==⎨⎪-+->⎩

做该实验,需要定义两个函数出口,则当n==0且n==1时,递归调用结束;程序结束。程序如下: #include using namespace std; int main() { int n,m; cout<<"输入:"<>n; int diguifblq(int n); for(int i=1;i<=n;i++)

{

m=diguifblq(i); cout<

int diguifblq(int n)

{

if(n<=1)

return 1;

else

return diguifblq(n-1)+diguifblq(n-2);

}

从得到的实验数据分析,该递归调用函数在n<=1时调用结束,返回数据为1,;输入的数据是16,则需要将前16项的数据依次两两相加得到。

3、二分查找

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列或者将序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。该实验是典型的分治算法,即将规模逐步减小得到。实验程序如下:

#include

#include

#include

using namespace std;

int main ()

{

int x,n,i;

cout<<"输入需要操作数的个数:";

cin>>n;

vector a(n);

int left=0;

int right=n-1;

int d;

cout<<"输入所有的数:";

for(i=0;i

cin>>a[i];

sort(a.begin(),a.end()); //调用排序函数,对输入的数据进行排序;

cout<<"输出排序后的数:"<

for(i=0;i

cout<

cout<

cout<<"输入要查找的数:"<

cin>>x;

while(a[left]<=a[right]) //查找数

{

int d=(right+left)/2;

if(x==a[d])

{cout<<"已经找到"<<"该数的位置是:"<

cout<<"再次输出该数的值:"<

return 0;

}

if (x>a[d])

{

left=d+1;

}

else right=d-1;

} cout<<"没有找到"<

return 0;

}

相关文档
最新文档