分治与递归算法实验

合集下载

算法实验报告

算法实验报告

实验一分治与递归算法的应用一、实验目的1.掌握分治算法的基本思想(分-治-合)、技巧和效率分析方法。

2.熟练掌握用递归设计分治算法的基本步骤(基准与递归方程)。

3.学会利用分治算法解决实际问题。

二 . 实验内容金块问题老板有一袋金块(共n块,n是2的幂(n≥2)),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。

假设有一台比较重量的仪器,希望用最少的比较次数找出最重和最轻的金块。

并对自己的程序进行复杂性分析。

三.问题分析:一般思路:假设袋中有n 个金块。

可以用函数M a x(程序1 - 3 1)通过n-1次比较找到最重的金块。

找到最重的金块后,可以从余下的n-1个金块中用类似法通过n-2次比较找出最轻的金块。

这样,比较的总次数为2n-3。

分治法:当n很小时,比如说,n≤2,识别出最重和最轻的金块,一次比较就足够了。

当n 较大时(n>2),第一步,把这袋金块平分成两个小袋A和B。

第二步,分别找出在A和B中最重和最轻的金块。

设A中最重和最轻的金块分别为HA 与LA,以此类推,B中最重和最轻的金块分别为HB 和LB。

第三步,通过比较HA 和HB,可以找到所有金块中最重的;通过比较LA 和LB,可以找到所有金块中最轻的。

在第二步中,若n>2,则递归地应用分而治之方法程序设计据上述步骤,可以得出程序1 4 - 1的非递归代码。

该程序用于寻找到数组w [ 0 : n - 1 ]中的最小数和最大数,若n < 1,则程序返回f a l s e,否则返回t r u e。

当n≥1时,程序1 4 - 1给M i n和M a x置初值以使w [ M i n ]是最小的重量,w [ M a x ]为最大的重量。

首先处理n≤1的情况。

若n>1且为奇数,第一个重量w [ 0 ]将成为最小值和最大值的候选值,因此将有偶,数个重量值w [ 1 : n - 1 ]参与f o r循环。

当n 是偶数时,首先将两个重量值放在for 循环外进行比较,较小和较大的重量值分别置为Min和Max,因此也有偶数个重量值w[2:n-1]参与for循环。

分治算法的实验报告

分治算法的实验报告

一、实验背景分治算法是一种常用的算法设计方法,其基本思想是将一个复杂问题分解成若干个相互独立的小问题,然后将小问题递归求解,最终将子问题的解合并为原问题的解。

分治算法具有高效性、可扩展性和易于实现等优点,被广泛应用于各个领域。

本实验旨在通过实现分治算法解决实际问题,掌握分治算法的设计思想,并分析其时间复杂度。

二、实验目的1. 理解分治算法的基本思想;2. 掌握分治算法的递归实现方法;3. 分析分治算法的时间复杂度;4. 应用分治算法解决实际问题。

三、实验内容本实验选择两个分治算法:快速排序和合并排序。

1. 快速排序快速排序是一种高效的排序算法,其基本思想是将待排序序列分为两个子序列,其中一个子序列的所有元素均小于另一个子序列的所有元素,然后递归地对两个子序列进行快速排序。

(1)算法描述:① 选择一个基准值(pivot),通常取序列的第一个元素;② 将序列分为两个子序列,一个子序列包含所有小于基准值的元素,另一个子序列包含所有大于基准值的元素;③ 递归地对两个子序列进行快速排序。

(2)代码实现:```cvoid quickSort(int arr[], int left, int right) {if (left < right) {int pivot = arr[left];int i = left;int j = right;while (i < j) {while (i < j && arr[j] >= pivot) {j--;}arr[i] = arr[j];while (i < j && arr[i] <= pivot) {i++;}arr[j] = arr[i];}arr[i] = pivot;quickSort(arr, left, i - 1);quickSort(arr, i + 1, right);}}```2. 合并排序合并排序是一种稳定的排序算法,其基本思想是将待排序序列分为两个子序列,分别对两个子序列进行排序,然后将排序后的子序列合并为一个有序序列。

分治算法实验报告

分治算法实验报告

算法分析与设计实验报告第 1 次实验if(maxi>maxj)max=maxi;elsemax=maxj;if(mini<minj)min=mini;elsemin=minj;return;}}srand((unsigned int)time(NULL));cout <〈”随机产生的数据(0—100):”;for(int i=0; i〈m; i++)a[i] = rand()%100;测试结果附录:完整代码SelectMaxMin.cpp:#include <iostream>#include <ctime>#include 〈cstdio>#include <iomanip>#include 〈cstdlib〉using namespace std;void SelectMaxMin(int *a,int i,int j,int &max,int &min) {if(i==j){max= a[i];min =a[i];return;}else{int mid=(i+j)/2;int maxi,maxj,mini,minj;SelectMaxMin(a,i,(i+j)/2,maxi,mini);SelectMaxMin(a,((i+j)/2)+1,j,maxj,minj);if(maxi〉maxj)max=maxi;elsemax=maxj;if(mini<minj)min=mini;elsemin=minj;return;}}int main(){clock_t start,end,over;start=clock();end=clock();over=end—start;start=clock();//freopen("in。

txt",”r",stdin);//freopen(”out。

txt”,”w",stdout);int m;cout 〈<"Please input the number : ”;cin>〉 m;int a[m];srand((unsigned int)time(NULL));cout 〈〈 "随机产生的数据(0-100):";for(int i=0; i〈m; i++)a[i] = rand()%100;for(int i=0; i〈m; i++)cout <〈 a[i] 〈< " ";cout 〈< endl;int max,min;SelectMaxMin(a,0,m-1,max,min);cout 〈< "max = " 〈〈 max 〈〈 endl;cout <〈”min = " <〈 min 〈〈 endl;end=clock();printf(”The time is %6.3f”,(double)(end-start—over)/CLK_TCK); }。

《算法设计与分析》实验报告实验一...

《算法设计与分析》实验报告实验一...

《算法设计与分析》实验报告实验一递归与分治策略应用基础学号:**************姓名:*************班级:*************日期:2014-2015学年第1学期第九周一、实验目的1、理解递归的概念和分治法的基本思想2、了解适用递归与分治策略的问题类型,并能设计相应的分治策略算法3、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:以下题目要求应用递归与分治策略设计解决方案,本次实验成绩按百分制计,完成各小题的得分如下,每小题要求算法描述准确且程序运行正确。

1、求n个元素的全排。

(30分)2、解决一个2k*2k的特殊棋牌上的L型骨牌覆盖问题。

(30分)3、设有n=2k个运动员要进行网球循环赛。

设计一个满足要求的比赛日程表。

(40分)提交结果:算法设计分析思路、源代码及其分析说明和测试运行报告。

三、设计分析四、算法描述及程序五、测试与分析六、实验总结与体会#include "iostream"using namespace std;#define N 100void Perm(int* list, int k, int m){if (k == m){for (int i=0; i<m; i++)cout << list[i] << " ";cout << endl;return;}else{for (int i=m; i<k; i++){swap(list[m], list[i]);Perm(list, k, m+1);swap(list[m], list[i]);}}}void swap(int a,int b){int temp;temp=a;a=b;b=temp;}int main(){int i,n;int a[N];cout<<"请输入排列数据总个数:";cin>>n;cout<<"请输入数据:";for(i=0;i<n;i++){cin>>a[i];}cout<<"该数据的全排列:"<<endl;Perm(a,n,0);return 0;}《算法设计与分析》实验报告实验二递归与分治策略应用提高学号:**************姓名:*************班级:*************日期:2014-2015学年第1学期一、实验目的1、深入理解递归的概念和分治法的基本思想2、正确使用递归与分治策略设计相应的问题的算法3、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:从以下题目中任选一题完成,要求应用递归与分治策略设计解决方案。

分治法实验心得

分治法实验心得

分治法实验心得分治法实验心得分治法是一种常见的算法设计策略,它将原问题划分成若干个规模较小但结构与原问题相似的子问题,然后递归地求解这些子问题,最终将子问题的解合并得到原问题的解。

在本次实验中,我们实现了两个基于分治法的算法:归并排序和快速排序,并对它们进行了性能测试和比较。

一、归并排序1. 原理归并排序是一种典型的分治算法。

它将待排序数组不断地二分为两个子数组,直到每个子数组只剩下一个元素。

然后将相邻的两个子数组合并成一个有序数组,再将相邻的两个有序数组合并成一个更大的有序数组,直到最终合并成整个待排序数组。

2. 实现我们采用了自顶向下的递归方式实现了归并排序。

具体来说,我们定义了一个merge函数用于合并两个有序子数组,并定义了一个sort 函数用于递归地对左右两个子数组进行排序和合并。

3. 性能测试与比较我们使用Python内置的time模块对不同规模(10^2 ~ 10^6)的随机整数列表进行了性能测试,并绘制出了运行时间随数组规模增大的变化曲线。

结果表明,归并排序的时间复杂度为O(nlogn),与理论分析相符。

二、快速排序1. 原理快速排序也是一种分治算法。

它选择一个基准元素,将数组中小于等于它的元素放在其左侧,大于它的元素放在其右侧。

然后递归地对左右两个子数组进行同样的操作,直到每个子数组只剩下一个元素。

2. 实现我们实现了两个版本的快速排序:递归版本和非递归版本。

其中,递归版本采用了经典的Lomuto分区方案,而非递归版本则采用了更高效的Hoare分区方案。

3. 性能测试与比较我们同样使用Python内置的time模块对不同规模(10^2 ~ 10^6)的随机整数列表进行了性能测试,并绘制出了运行时间随数组规模增大的变化曲线。

结果表明,快速排序具有很好的平均时间复杂度(O(nlogn)),但最坏情况下时间复杂度会退化到O(n^2)。

三、总结与思考通过本次实验,我们深入理解了分治算法设计策略,并学会了如何实现归并排序和快速排序。

算法设计与分析:递归与分治法-实验报告(总8页)

算法设计与分析:递归与分治法-实验报告(总8页)

算法设计与分析:递归与分治法-实验报告(总8页)实验目的:掌握递归与分治法的基本思想和应用,学会设计和实现递归算法和分治算法,能够分析和评价算法的时间复杂度和空间复杂度。

实验内容:1.递归算法的设计与实现3.算法的时间复杂度和空间复杂度分析实验步骤:1)递归定义:一个函数或过程,在其定义或实现中,直接或间接地调用自身的方法,被成为递归。

递归算法是一种控制结构,它包含了解决问题的基础情境,也包含了递归处理的情境。

2)递归特点:递归算法具有以下特点:①依赖于递归问题的部分解被划分为若干较小的部分。

②问题的规模可以通过递推式递减,最终递归终止。

③当问题的规模足够小时,可以直接求解。

3)递归实现步骤:①确定函数的定义②确定递归终止条件③确定递归调用的过程4)经典实例:斐波那契数列递推式:f(n) = f(n-1) + f(n-2)int fib(int n) {if (n <= 0)return 0;else}5)优化递归算法:避免重复计算例如,上述斐波那契数列的递归算法会重复计算一些中间结果,影响效率。

可以使用动态规划技术,将算法改为非递归形式。

int f1 = 0, f2 = 1;for (int i = 2; i <= n; i++) {f1 = f2;使用循环避免递归,重复计算可以大大减少,提高效率。

1)分治算法的定义:将原问题分解成若干个规模较小且类似的子问题,递归求解子问题,然后合并各子问题得到原问题的解。

2)分治算法流程:②将问题分解成若干个规模较小的子问题。

③递归地解决各子问题。

④将各子问题的解合并成原问题的解。

3)分治算法实例:归并排序归并排序是一种基于分治思想的经典排序算法。

排序流程:②分别对各子数组递归进行归并排序。

③将已经排序好的各子数组合并成最终的排序结果。

实现源代码:void mergeSort(int* arr, int left, int right) {if (left >= right)while (i <= mid && j <= right)temp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];temp[k++] = arr[i++];1) 时间复杂度的概念:指完成算法所需的计算次数或操作次数。

算法之2章递归与分治

算法之2章递归与分治

算法分析(第二章):递归与分治法一、递归的概念知识再现:等比数列求和公式:1、定义:直接或间接地调用自身的算法称为递归算法。

用函数自身给出定义的函数称为递归函数。

2、与分治法的关系:由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。

在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。

这自然导致递归过程的产生。

分治与递归经常同时应用在算法设计之中,并由此产生许多高效算法。

3、递推方程:(1)定义:设序列01,....na a a简记为{na},把n a与某些个()ia i n<联系起来的等式叫做关于该序列的递推方程。

(2)求解:给定关于序列{n a}的递推方程和若干初值,计算n a。

4、应用:阶乘函数、Fibonacci数列、Hanoi塔问题、插入排序5、优缺点:优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。

缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。

二、递归算法改进:1、迭代法:(1)不断用递推方程的右部替代左部(2)每一次替换,随着n的降低在和式中多出一项(3)直到出现初值以后停止迭代(4)将初值代入并对和式求和(5)可用数学归纳法验证解的正确性2、举例:-----------Hanoi塔算法----------- ---------------插入排序算法----------- ()2(1)1(1)1T n T nT=−+=()(1)1W n W n nW=−+−(1)=021n-23()2(1)12[2(2)1]12(2)21...2++2 (121)n n n T n T n T n T n T −−=−+=−++=−++==++=−(1)2 ()(1)1((n-2)+11)1(2)(2)(1)...(1)12...(2)(1)(1)/2W n W n n W n n W n n n W n n n n =−+−=−−+−=−+−+−==++++−+−=−3、换元迭代:(1)将对n 的递推式换成对其他变元k 的递推式 (2)对k 进行迭代(3)将解(关于k 的函数)转换成关于n 的函数4、举例:---------------二分归并排序---------------()2(/2)1W n W n n W =+−(1)=0(1)换元:假设2kn =,递推方程如下()2(/2)1W n W n n W =+−(1)=0 → 1(2)2(2)21k k k W W W−=+−(0)=0(2)迭代求解:12122222321332133212()2(2)212(2(2)21)212(2)22212(2)2*2212(2(2)21)2212(2)222212(2)3*2221...2(0)*2(22...21)22k k k k k k k k k k k k k k k k k k k k k k k k W n W W W W W W W W k k −−−−−−−+−+−−−=+−=+−+−=+−+−=+−−=+−+−−=+−+−−=+−−−==+−++++=−1log 1n n n +=−+(3)解的正确性—归纳验证: 证明递推方程的解是()(1)/2W n n n =−()(1)1W n W n n W =−+−(1)=0,(n 1)=n +n=n(n-1)/2+n =n[(n-1)/2+1]=n(n+1)/2n W W +方法:数学归纳法证 n=1,W(1)=1*(1-1)/2=0假设对于解满足方程,则()---------------快速排序--------------------->>>平均工作量:假设首元素排好序在每个位置是等概率的112()()()(1)0n i T n T i O n n T −==+=∑ >>>对于高阶方程应该先化简,然后迭代(1)差消化简:利用两个方程相减,将右边的项尽可能消去,以达到降阶的目的。

分治法实验总结

分治法实验总结

分治法实验总结
分治法是一种常用的算法设计策略,它将问题分解成若干个子问题,然后递归地解决这些子问题,最后将子问题的解合并成原问题的解。

在本次实验中,我们通过实现归并排序和快速排序两个算法,深入理解了分治法的思想和实现方式。

我们实现了归并排序算法。

归并排序的基本思想是将待排序的序列分成若干个子序列,每个子序列都是有序的,然后再将子序列合并成一个有序的序列。

在实现过程中,我们采用了递归的方式,将序列不断地分成两半,直到每个子序列只有一个元素,然后再将这些子序列两两合并,直到最终得到一个有序的序列。

归并排序的时间复杂度为O(nlogn),是一种稳定的排序算法。

接着,我们实现了快速排序算法。

快速排序的基本思想是选择一个基准元素,将序列分成两个部分,一部分比基准元素小,一部分比基准元素大,然后递归地对这两个部分进行排序。

在实现过程中,我们选择了序列的第一个元素作为基准元素,然后使用两个指针分别从序列的两端开始扫描,将比基准元素小的元素放在左边,将比基准元素大的元素放在右边,最后将基准元素放在中间,然后递归地对左右两个部分进行排序。

快速排序的时间复杂度为O(nlogn),但是在最坏情况下,时间复杂度会退化为O(n^2)。

通过实现归并排序和快速排序两个算法,我们深入理解了分治法的
思想和实现方式。

分治法是一种非常重要的算法设计策略,可以用来解决很多复杂的问题,比如最近点对问题、矩阵乘法问题等。

在实际应用中,我们可以根据具体问题的特点选择合适的分治算法,以提高算法的效率和准确性。

分治法实验报告范文

分治法实验报告范文

一、实验目的及要求
利用分治方法设计大整数乘法的递归算法,掌握分治法的基本思想和算法设计的基本步骤。

要求:设计十进制的大整数乘法,必须利用分治的思想编写算法,利用c 语言(或者c++语言)实现算法,给出程序的正确运行结果。

(必须完成)设计二进制的大整数乘法,要求利用分治的思想编写递归算法,并可以实现多位数的乘法(利用数组实现),给出程序的正确运行结果。

(任选)
二、算法描述
输入两个相同位数的大整数u,v
输出uv的值
判断大整数的位数i;
w=u/10^(i/2);
y=v/10^(i/2);
x=u-w*10^(i/2);
z=v-y*10^(i/2);
然后将w,x,y,z代入公式求得最后结果
uv=wy10^i+((w+x)(y+z)-wy-xz)10^(i/2)+xz
三、调试过程及运行结果
在实验中我遇到的问题:
原来以为这两个大整数的位数不同,结果题目要求是相同位数的大整数在写10的多少次方时,写的是10^(i/2),10^(i),结果不对,我就将它改成了for循环语句
四、实验总结
在本次实验中,我知道了分治算法,以及分治算法的基本思想。

我还掌握了编写大整数乘法的算法与步骤,以及如何修改在编写程序时遇到的问题。

基于分治和递归策略的排序算法及实现

基于分治和递归策略的排序算法及实现
序 算法比较 , 算法在各种情 况下的交换次数均明显 少于经典的选择排序算法。 该
关键 词 :排序 ;关 键 字 ;分 治 ;递 归
中图分类号 : P 1 T 32
文献标志码 :A
文章编号 :0 6 8 2 (0 2 0 — 7 0 10 i a g ihm bas d o di i — nd- o e n v de a c nque t a e y nd e ur i e t at g a t r a i a i r s r t g a r c sv s r e y nd is e lz ton
b s d n i i e a d c n u r n r c r i e ta e is s u f r a d Co a e o d v d — n — o q e a d e u sv sr t g e i p t o w r . mpa e wi s l c i n o tn a g rt m, t e x ha g n rd t h ee to s ri g l o h i h e c n i g fe u n y f t s l o t m s o v o sy l s h n t a f ca sc e e t n o i g l o t m u e a o s c r u t n e . r q e c o hi a g r h i b i u l e s t a t o l s i s l ci s r n ag r h i h o t i nd r v r u ic ms a c s i K e r s s ri g;k y r y wo d : o t n e wo d; d v d a d c n u r r c r i n i i e n o q e ; e u so

算法与设计实验报告

算法与设计实验报告

实验一分治与递归(4学时)一、实验目的与要求1、熟悉C/C++语言的集成开发环境;2、通过本实验加深对递归过程的理解二、实验内容掌握递归算法的概念和基本思想,分析并掌握“整数划分”问题的递归算法。

三、实验题任意输入一个整数,输出结果能够用递归方法实现整数的划分。

四、程序代码五、实验结果首先按照提示输入数字:按回车键,得到此数划分的个数:此时您可以接着计算另一个数的划分个数:若要退出,请输入一个小于等于零的数:六、结果分析及程序功能经过和其它同学的实验数据对比,初步认定此程序基本正确,然而不足之处是只能得到划分的个数,而不能列出每个划分的详细情况。

一、实验目的与要求1、掌握棋盘覆盖问题的算法;2、初步掌握分治算法二、实验题盘覆盖问题:在一个2k×2k个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。

在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。

三、程序代码四、实验结果按照提示输入特殊方格的行号和列号(起始行列号为0):按回车键,得到一个矩阵,数字相同区域为一个L型骨牌覆盖:五、结果分析及程序功能得到的16*16棋盘覆盖结果正确,此程序的不足之处:只能设定特殊方格的行列号,而不能设定棋盘的大小。

实验二动态规划算法(4学时)一、实验目的与要求1、熟悉最长公共子序列问题的算法;2、初步掌握动态规划算法;二、实验题若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:zj=xij。

例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。

给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。

分治法实验总结

分治法实验总结

分治法实验总结
分治法是一种重要的算法思想,它的核心思想就是将单个问题划
分为多个相似的子问题,并通过递归思想将这些子问题分别解决,最
终合并起来得到整个问题的解。

在算法设计中,应用分治法能够提高
算法的效率,减少时间复杂度,实现更加高效的计算。

在实验中,我们通过使用分治法,解决了两个典型的问题:二分
查找和归并排序。

在二分查找中,我们将数组一分为二,通过递归思
想分别查找数组左半部分和右半部分,最终得到目标元素在数组中的
位置。

在归并排序中,我们同样将数组一分为二,分别对两个子数组
进行排序,然后通过归并操作将排序好的子数组合并为一个有序数组。

通过实验我们发现,使用分治法可以大大提高算法效率,减少时
间复杂度。

在二分查找算法中,平均时间复杂度为O(log n),比传统
的线性查找算法时间复杂度要低得多。

在归并排序中,时间复杂度为
O(nlogn),比传统的冒泡排序、插入排序更加高效。

总的来说,分治法是一种高效、可拓展的算法思想,能够为我们
解决一些复杂的算法问题提供帮助。

在具体的应用过程中,我们还需
要加强对算法的理解和分析能力,结合具体问题进行灵活的算法设计
和选择,以达到更好的效果。

(算法分析设计)第2章递归与分治策略

(算法分析设计)第2章递归与分治策略
后两种方法在时空复杂度上均有较大改善, 但其适用范围有限。
分治法的基本思想
分治法的基本思想
将一个规模为n的问题分解为a个规模较小的子 问题,这些子问题互相独立并且与原问题相同。 通过递归地求解这些子问题,然后再将各个子问 题的解合并,就可以实现对原问题的求解。
分治法的求解过程
分治法的求解过程
表示以塔座b为辅助塔座,将塔座a 上自下而上,由大到小叠在一起的 n-1个圆盘按规则移至塔座c上并 按同样顺序叠放。
将塔座a上的圆盘移动 到塔座b上去
Hanoi塔问题的复杂性分析
n=1
移动次数T(1)=1
n=2
移动次数T(2)=3
n=3
移动次数T(3)=7
n=4
移动次数T(4)=15
divide-and-conquer(P) {
if(|P|<=n0) adhoc(P);
n0:阀值
如果问题P的规模不超过n0,说明 问题已经容易求解,不要再继续 分解。利用adhoc(P)直接求解。
divide P into smaller subinstances P1,P2,…,Pa;
for(i=1,i<=a,i++)
T ( n ) ( n lo g b a ) O ( n lo g b a ) ( n lo g b a )
T ( n ) ( n l o g b a ) ( n l o g b a l g n ) ( n l o g b a l g n )
T ( n )( n lo g b a )(f( n ) )(f( n ) )
二分搜索技术 大整数的乘法 Strassen矩阵乘法 合并排序 快速排序 线性时间选择
二分搜索技术

递归实验报告

递归实验报告

递归实验报告篇一:字符串,递归实验报告宁波工程学院电信学院计算机教研室实验报告一、实验目的1)熟悉串的定义和串的基本操作。

2)加深对串数据结构的理解,逐步培养解决实际问题的编程能力。

3)熟悉递归的定义和递归的算法设计。

4)加深对递归算法的理解,逐步培养解决实际问题的编程能力。

二、实验环境装有Visual C++6.0的计算机。

三、实验内容1、凯撒加密算法凯撒密码(caeser)是罗马扩张时期朱利斯?凯撒(Julius Caesar)创造的,用于加密通过信使传递的作战命令。

它将字母表中的字母移动一定位置而实现加密。

他的原理很简单,说到底就是字母与字母之间的替换。

每一个字母按字母表顺序向后移3位,如a加密后变成d,b加密后变成e,······x加密后变成a,y加密后变成b,z加密后变成c。

例如:“baidu”用凯撒密码法加密后字符串变为“edlgx”。

试写一个算法,将键盘输入的文本字符串(只包含a~z 的字符)进行加密后输出。

另写一个算法,将已加密后的字符串解密后输出。

提示:? 如果有字符变量c加密后则=’a’+(c-‘a’+3)%26? 采用顺序结构存储串,键盘输入字符串后保存到顺序串中;输出用顺序串的输出函数。

程序:#include#define MaxSize 100typedef struct //串的类型定义char ch[MaxSize];//存放串字符int len; //串长}SqString;void SetString(SqString &s) //设置源码{int i;printf("请输入原字符串:");scanf("%s",s.ch);for(i=0;s.ch[i]!='\0';i++); //计算串的长度s.len=i;}void TranString(SqString s,SqString &t)//开始加密{int i;for(i=0;i {if(s.ch[i]>='a'&&s.ch[i] t.ch[i]='a'+(s.ch[i]-'a'+3)%26; //将每一个字母按字母表顺序向后移3位elset.ch[i]=s.ch[i];//如果字符不是字母a~z,则原样保留}t.len=s.len;}void RecoverString(SqString s,SqString &t) //开始解密{int i;for(i=0;i {if(s.ch[i]>='d'&&s.ch[i] t.ch[i]=s.ch[i]-3;else if(s.ch[i]>='a'&&s.ch[i] t.ch[i]=s.ch[i]+23;elset.ch[i]=s.ch[i]; //如果字符不是字母a~z,则原样保留 }t.len=s.len;}void DispString(SqString s) //输出字符串int i=0;while(i {printf("%c",s.ch[i]); //字母的逐个输出i++;}printf("\n");}int main(){SqString s1,s2,s3; //s1是源码,s2是加密后密码,s3是解密后密码SetString(s1); //输入字符串DispString(s1); //输出字符串TranString(s1,s2);//加密DispString(s2); //加密后输出字符串RecoverString(s2,s3);//解密DispString(s3); //解密后输出字符串return 0;}按实验要求首先定义顺序串,实验的难点在于密码的加密和解密的实现,特别是再解密时,字母的溢出问题,在参考网上程序后很好地解决了这个问题。

递归问题实验报告

递归问题实验报告

一、实验目的1. 理解递归算法的基本概念和原理。

2. 掌握递归算法的设计方法和实现技巧。

3. 通过具体实例,加深对递归算法在实际问题中的应用。

二、实验内容本次实验主要针对递归算法在排序、查找和数学问题中的应用进行探讨。

1. 排序问题(1)实验目的:使用递归算法实现快速排序。

(2)实验原理:快速排序是一种分而治之的排序算法。

其基本思想是:选取一个基准元素,将数组分为两个子数组,一个子数组的所有元素都比基准元素小,另一个子数组的所有元素都比基准元素大,然后递归地对两个子数组进行快速排序。

(3)实验步骤:① 定义一个递归函数,用于实现快速排序;② 在递归函数中,选择基准元素,并根据基准元素将数组分为两个子数组;③ 递归地对两个子数组进行快速排序;④ 输出排序后的数组。

(4)实验结果:通过实际编程,验证快速排序算法的正确性。

2. 查找问题(1)实验目的:使用递归算法实现折半查找。

(2)实验原理:折半查找是一种基于二分查找思想的递归查找算法。

其基本思想是:将待查找的序列分为两个子序列,然后确定目标值所在子序列,递归地对子序列进行查找。

(3)实验步骤:① 定义一个递归函数,用于实现折半查找;② 在递归函数中,根据目标值与中间元素的比较结果,确定目标值所在子序列;③ 递归地对子序列进行查找;④ 输出查找结果。

(4)实验结果:通过实际编程,验证折半查找算法的正确性。

3. 数学问题(1)实验目的:使用递归算法求解斐波那契数列。

(2)实验原理:斐波那契数列是一个著名的数列,其递推公式为:F(n) = F(n-1) + F(n-2),其中F(1) = 1,F(2) = 1。

(3)实验步骤:① 定义一个递归函数,用于计算斐波那契数列的第n项;② 在递归函数中,根据n的值,计算斐波那契数列的第n项;③ 输出斐波那契数列的第n项。

(4)实验结果:通过实际编程,验证斐波那契数列递归算法的正确性。

三、实验总结1. 通过本次实验,我们对递归算法的基本概念和原理有了更深入的理解。

分治法金块实验报告

分治法金块实验报告

分治法金块实验报告引言分治法是一种高效的问题解决方法,通过将问题划分为多个子问题并递归地解决,然后将子问题的解合并得到原始问题的解。

本次实验使用了分治法解决了金块分割问题。

金块分割问题是将一块金块分割成多个相等大小的小块的问题。

实验目的本次实验旨在通过实践掌握分治法的应用,了解其原理和算法实现,进一步加深对分治法的理解。

实验步骤1. 首先,将一块金块均匀分割成4块。

2. 然后,从4块金块中找到最重的一块。

3. 接着,将最重的金块与其他3块再次均匀分割成4块。

4. 重复上述过程,直到金块的数量足够小无法再分割。

5. 最后,计算并输出得到的最重金块的重量。

实验结果通过实验,我们得到了一块金块分割的过程及最终的结果。

实验中,我们使用了递归的方法来实现分治法。

以下是分治法金块分割的过程演示:1. 原始金块:10 kg2. 第一次分割:10 kg -> 2.5 kg + 2.5 kg + 2.5 kg + 2.5 kg3. 第二次分割:2.5 kg -> 0.625 kg + 0.625 kg + 0.625 kg + 0.625 kg4. 第三次分割:0.625 kg -> 0.15625 kg + 0.15625 kg + 0.15625 kg +0.15625 kg5. 第四次分割:0.15625 kg -> 0.03906 kg + 0.03906 kg + 0.03906 kg + 0.03906 kg6. 第五次分割:0.03906 kg -> 0.00977 kg + 0.00977 kg + 0.00977 kg + 0.00977 kg7. 第六次分割:0.00977 kg -> 0.00244 kg + 0.00244 kg + 0.00244 kg + 0.00244 kg8. 第七次分割:0.00244 kg -> 0.00061 kg + 0.00061 kg + 0.00061 kg + 0.00061 kg9. 第八次分割:0.00061 kg -> 0.00015 kg + 0.00015 kg + 0.00015 kg + 0.00015 kg经过八次分割,最终得到的金块重量是0.00015 kg。

算法设计与分析实验报告

算法设计与分析实验报告

本科实验报告课程名称:算法设计与分析实验项目:递归与分治算法实验地点:计算机系实验楼110专业班级:物联网1601 学号:2016002105 学生姓名:俞梦真指导教师:郝晓丽2018年05月04 日实验一递归与分治算法1.1 实验目的与要求1.进一步熟悉C/C++语言的集成开发环境;2.通过本实验加深对递归与分治策略的理解和运用。

1.2 实验课时2学时1.3 实验原理分治(Divide-and-Conquer)的思想:一个规模为n的复杂问题的求解,可以划分成若干个规模小于n的子问题,再将子问题的解合并成原问题的解。

需要注意的是,分治法使用递归的思想。

划分后的每一个子问题与原问题的性质相同,可用相同的求解方法。

最后,当子问题规模足够小时,可以直接求解,然后逆求原问题的解。

1.4 实验题目1.上机题目:格雷码构造问题Gray码是一个长度为2n的序列。

序列无相同元素,每个元素都是长度为n的串,相邻元素恰好只有一位不同。

试设计一个算法对任意n构造相应的Gray码(分治、减治、变治皆可)。

对于给定的正整数n,格雷码为满足如下条件的一个编码序列。

(1)序列由2n个编码组成,每个编码都是长度为n的二进制位串。

(2)序列中无相同的编码。

(3)序列中位置相邻的两个编码恰有一位不同。

2.设计思想:根据格雷码的性质,找到他的规律,可发现,1位是0 1。

两位是00 01 11 10。

三位是000 001 011010 110 111 101 100。

n位是前n-1位的2倍个。

N-1个位前面加0,N-2为倒转再前面再加1。

3.代码设计:}}}int main(){int n;while(cin>>n){get_grad(n);for(int i=0;i<My_grad.size();i++)cout<<My_grad[i]<<endl;My_grad.clear();}return 0;}运行结果:1.5 思考题(1)递归的关键问题在哪里?答:1.递归式,就是如何将原问题划分成子问题。

《算法设计与分析》课程实验报告 (分治法(三))

《算法设计与分析》课程实验报告 (分治法(三))

《算法设计与分析》课程实验报告实验序号:04实验项目名称:实验4 分治法(三)一、实验题目1.邮局选址问题问题描述:在一个按照东西和南北方向划分成规整街区的城市里,n个居民点散乱地分布在不同的街区中。

用x 坐标表示东西向,用y坐标表示南北向。

各居民点的位置可以由坐标(x,y)表示。

街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值∣x1−x2∣+∣y1−y2∣度量。

居民们希望在城市中选择建立邮局的最佳位置,使n个居民点到邮局的距离总和最小。

编程任务:给定n 个居民点的位置,编程计算邮局的最佳位置。

2.最大子数组问题问题描述:对给定数组A,寻找A的和最大的非空连续子数组。

3.寻找近似中值问题描述:设A是n个数的序列,如果A中的元素x满足以下条件:小于x的数的个数≥n/4,且大于x的数的个数≥n/4 ,则称x为A的近似中值。

设计算法求出A的一个近似中值。

如果A中不存在近似中值,输出false,否则输出找到的一个近似中值4.循环赛日程表问题描述:设有n=2^k个运动员要进行网球循环赛。

现要设计一个满足以下要求的比赛日程表:每个选手必须与其他n-1个选手各赛一次,每个选手一天只能赛一次,循环赛一共进行n-1天。

二、实验目的(1)进一步理解分治法解决问题的思想及步骤(2)体会分治法解决问题时递归及迭代两种不同程序实现的应用情况之差异(3)熟练掌握分治法的自底向上填表实现(4)将分治法灵活于具体实际问题的解决过程中,重点体会大问题如何分解为子问题及每一个大问题涉及哪些子问题及子问题的表示。

三、实验要求(1)写清算法的设计思想。

(2)用递归或者迭代方法实现你的算法,并分析两种实现的优缺点。

(3)根据你的数据结构设计测试数据,并记录实验结果。

(4)请给出你所设计算法的时间复杂度的分析,如果是递归算法,请写清楚算法执行时间的递推式。

四、实验过程(算法设计思想、源码)1.邮局选址问题(1)算法设计思想根据题目要求,街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值∣x1−x2∣+∣y1−y2∣度量。

《算法设计与分析》实验目的

《算法设计与分析》实验目的

《算法设计与分析》实验指导书曹严元计算机与信息科学学院2007年5月目录实验一递归算法与非递归算法 (2)实验二分治算法 ................................................... 错误!未定义书签。

实验三贪心算法 (3)实验四动态规划 (2)实验五回溯法 (3)实验六分枝—限界算法 (4)实验七课程设计 (4)实验一递归与分治算法实验目的1.了解并掌握递归的概念,掌握递归算法的基本思想;2.掌握分治法的基本思想方法;3.了解适用于用递归与分治求解的问题类型,并能设计相应递归与分治算法;4.掌握递归与分治算法复杂性分析方法,比较同一个问题的递归算法与循环迭代算法的效率。

实验二动态规划实验目的1.掌握动态规划的基本思想方法;2.了解适用于用动态规划方法求解的问题类型,并能设计相应动态规划算法;3.掌握动态规划算法复杂性分析方法。

实验三贪心算法实验目的1.掌握贪心法的基本思想方法;2.了解适用于用贪心法求解的问题类型,并能设计相应贪心法算法;3.掌握贪心算法复杂性分析方法分析问题复杂性。

实验五回溯法实验目的1.掌握回溯法的基本思想方法;2.了解适用于用回溯法求解的问题类型,并能设计相应回溯法算法;3.掌握回溯法算法复杂性分析方法,分析问题复杂性。

实验六 分枝—限界算法实验目的1. 掌握分枝—限界的基本思想方法;2. 了解适用于用分枝—限界方法求解的问题类型,并能设计相应动态规划算法;3. 掌握分枝—限界算法复杂性分析方法,分析问题复杂性。

实验七 课程设计实验目的1. 在已学的算法基本设计方法的基础上,理解算法设计的基本思想方法;2. 掌握对写出的算法的复杂性分析的方法,理解算法效率的重要性;3. 能运用所学的基本算法设计方法对问题设计相应算法,分析其效率,并建立对算法进行改进,提高效率的思想意识。

预习与实验要求1. 预习实验指导书及教材的有关内容,回顾所学过的算法的基本思想;2. 严格按照实验内容进行实验,培养良好的算法设计和编程的习惯;3. 认真听讲,服从安排,独立思考并完成实验。

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

实验二分治与递归算法的应用
一、实验目的
1.掌握分治算法的基本思想(分-治-合)、技巧和效率分析方法。

2.熟练掌握用递归设计分治算法的基本步骤(基准与递归方程)。

3.学会利用分治算法解决实际问题。

二、实验内容
1.问题描述:
题目一:线性时间选择
给定n个元素和一个整数k,要求用O(n)时间找出这n个元素中第k小元素。

题目二:金块问题
老板有一袋金块(共n块,n是2的幂(n≥2)),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。

假设有一台比较重量的仪器,希望用最少的比较次数找出最重和最轻的金块。

并对自己的程序进行复杂性分析。

【输入输出样例】
题目三:求最大两个数和最小两个数
利用分治法求一组数据中最大的两个数和最小的两个数。

2.数据输入:个人设定,由键盘输入。

3.要求:
1)上述题目任选其二。

上机前,完成程序代码的编写
2)独立完成实验及实验报告
三、实验步骤
1.理解算法思想和问题要求;
2.编程实现题目要求;
3.上机输入和调试自己所编的程序;
4.验证分析实验结果;
5.整理出实验报告。

一.实验目的
二.问题描述
三.算法设计
包含:数据结构与核心算法的设计描述、函数调用及主函数设计、主要算法流程图等
1.金块问题:考虑到可能输入数据有一个或者两个这种情况,
所以解决问题时分三种情况考虑,然后通过函数调用来实现寻
找最大最小的数值。

复杂性分析:当n是2的幂时,即对于
某个正整数k,n等于2的k次方,可以证明,任何以元素比
较为基础的找最大和最小元素的算法,其元素比较下界均为
[3n/2]-2次。

因此,过程maxmin在这种意义上是最优的。

T(n)=2T(n/2)+2
2.最大最小两个数:与金块问题类似,这是寻找最大最小的两个
数。

利用循环嵌套条件语句进行判断,选择出最大最小的两个
数。

四.程序调试及运行结果分析
1)有五个金块,其重量分别为2.3,1.3 ,6.9, 2, 1成功运行程
序后输出最重和最轻的金块的重量。

2)如下图所示,输入六个数分别为:5,9,12,3,16,2 成功运行后,
输出最大的2个元素16,12最小的2个元素2,3。

五.实验总结
通过本次实验,我学会了如何运用分治法将整个问题分解成若干个小问题后分而治之,使其产生出方便求解的子问题,必要时逐步合并这些子问题的解,从而得到问题的解。

在实验中我观察了相关算法结合老师上课讲解的,我觉得这类问题实际可以用一个递归方程来表示,通过递归逐步求解问题。

同时,通过本次实验我也发现递归算法的重要性,自己对递归算法还不能熟练的应用。

所以,在课下我会继续努
力掌握这种算法,以便能在以后熟练的应用它。

通过第三题明白了眼过千变不如手动一遍,上课是听懂了.课下我又仔细的上网看了研究了一下,但是今天敲出来还是有一些问题,我觉得一些问题是值得注意的.
附录:程序清单(程序过长,可附主要部分)
1)金块问题程序如下:
#include<iostream>
using namespace std;
int i,n;
float a[100];
void maxmin(int i,int j,float &fmax,float &fmin)
{
int mid;
float lmax,lmin,rmax,rmin;
if(i==j)
{
fmax=a[i];
fmin=a[i];
}
else if(i==j-1)
if(a[i]<a[j])
{
fmax=a[j];
fmin=a[i];
}
else
{
fmax=a[i];
fmin=a[j];
}
else
{
mid=(i+j)/2;
maxmin(i,mid,lmax,lmin);
maxmin(mid+1,j,rmax,rmin);
if(lmax>rmax)
fmax=lmax;
else
fmax=rmax;
if(lmin>rmin)
fmin=rmin;
else
fmin=lmin;
}
}
int main()
{
cout<<"请输入金块的数量:"<<endl;
cin>>n;
cout<<"请输入"<<n<<"块金子的重量"<<endl;
for(i=1;i<=n;i++)
cin>>a[i];
float max,min;
maxmin(1,n,max,min);
cout<<"最重金块是"<<max<<" "<<"最轻金块是"<<min<<endl;
return 0;
}
2)求最大两个数和最小两个数
#include<iostream>
using namespace std;
int a[100];
void _maxmin(int i,int j,int *max1,int *min1,int *max2,int *min2) {
int max,min,minmax,minmin;
if(i==j)
{
*max1=*min1=*min2=*max2=a[i];
}
else
{
if(i==j-1)
{
if(a[i]<a[j])
{
*max1=*min2=a[j];
*min1=*max2=a[i];
}
else
{
*max1=*min2=a[i];
*min1=*max2=a[j];
}
}
else
{
int m=(i+j)/2;
_maxmin(i,m,max1,min1,max2,min2);
_maxmin(m+1,j,&max,&min,&minmax,&minmin);
if(*max1<max)
{
*max2=*max1;
*max1=max;
if(max!=minmax)
{
if(*max2<minmax)
{
*max2=minmax;
}
}
}
else
{
if(*max2<max)
{
*max2=max;
}
}
if(*min1>min)
{
*min2=*min1;
*min1=min;
if(min!=minmin)
if(*min2>minmin)
{
*min2=minmin;
}
}
else
{
if(*min2>min)
{
*min2=min;
}
}
}
}
}
int main()
{
int n,i,m,max[2],min[2];
cout<<"你要输入几个数?"<<endl;
cin>>n;
cout<<"请分别输入:"<<endl;
for(i=0;i<n;i++)
{
cin>>m;
a[i]=m;
}
_maxmin(0,n-1,&max[0],&min[0],&max[1],&min[1]);
cout<<"输入的数中最大的2个元素为:"<<max[0]<<" "<<max[1]<<endl;
cout<<"输入的数中最小的2个元素为:"<<min[0]<<" "<<min[1]<<endl;
return 0;
}。

相关文档
最新文档