递归与分治实验报告

合集下载

递归与分治算法心得

递归与分治算法心得

递归与分治算法心得
递归与分治算法都是常用的算法思想,可以很好地解决复杂问题。

递归算法是通过将问题分解为相同或相似的子问题来解决整个问题,然后再逐步合并回原问题的过程。

递归算法通常需要明确边界条件,以确保递归能够正确地停止。

分治算法是将问题分解成若干个相同或相似的子问题,递归地解决这些子问题,然后合并这些子问题的解来解决原始问题。

通常,分治算法可以高效地解决问题,但需要注意分解问题的方式和合并子问题的解的过程。

在实际应用中,递归和分治算法可以相互结合,以解决更加复杂的问题。

例如,可以使用分治算法来将问题分解成多个子问题,然后使用递归算法来解决这些子问题。

此外,还可以在递归算法中使用分治算法来对子问题进行分解和合并。

总而言之,递归与分治算法都是非常有用的算法思想,可以在许多领域中得到应用。

但是,在实际使用时,需要仔细考虑问题的性质和算法的复杂度,以确保算法的正确性和效率。

- 1 -。

递归与分治算法心得

递归与分治算法心得

递归与分治算法心得
递归与分治算法是算法设计中常见的两种方法,它们在解决问题时都采用了“分而治之”的思想,将问题分解成更小的子问题,然后通过递归调用或者合并子问题的解来得到原问题的解。

通过我的学习和实践,我深刻认识到了递归与分治算法的重要性和优势。

首先,递归算法可以使问题的描述更加简单明了。

通过将问题转化为自身的子问题,我们可以建立起更为简洁优美的数学模型。

其次,递归算法可以使问题的解决过程更加自然。

在递归过程中,我们可以利用已知的子问题解决同类问题,实现代码的复用和模块化。

此外,递归算法还可以解决一些重要的数学问题,如斐波那契数列和二分查找等。

分治算法则更加注重问题的分解和合并。

它将问题划分成若干个规模相同或相近的子问题,然后将子问题的解合并起来得到原问题的解。

这种方法在解决某些复杂问题时具有很大的优势。

例如,在排序算法中,归并排序采用了分治算法的思想,将待排序的序列分成两个长度相等的子序列,然后递归地对子序列排序,最后将子序列合并成有序序列。

这种算法具有较高的稳定性和灵活性,常常被应用于海量数据的排序任务中。

总之,递归与分治算法是算法设计中不可或缺的两种方法。

在解决问题时,我们应该根据具体情况选择合适的算法,并在实践中不断探索、总结和优化。

只有这样,我们才能更好地应对日益复杂多变的计算机科学挑战。

算法实验报告

算法实验报告

实验一分治与递归算法的应用一、实验目的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.提高学生综合应用所学知识解决实际问题的能力。

二、实验内容1、①设a[0:n-1]是已排好序的数组。

请写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。

当搜索元素在数组中时,i和j相同,均为x在数组中的位置。

②写出三分搜索法的程序。

三、实验要求(1)用分治法求解上面两个问题;(2)再选择自己熟悉的其它方法求解本问题;(3)上机实现所设计的所有算法;四、实验过程设计(算法设计过程)1、已知a[0:n-1]是一个已排好序的数组,可以采用折半查找(二分查找)算法。

如果搜索元素在数组中,则直接返回下表即可;否则比较搜索元素x与通过二分查找所得最终元素的大小,注意边界条件,从而计算出小于x的最大元素的位置i和大于x的最小元素位置j。

2、将n个元素分成大致相同的三部分,取在数组a的左三分之一部分中继续搜索x。

如果x>a[2(n-1)/3],则只需在数组a的右三分之一部分中继续搜索x。

上述两种情况不成立时,则在数组中间的三分之一部分中继续搜索x。

五、实验结果分析二分搜索法:三分搜索法:时间复杂性:二分搜索每次把搜索区域砍掉一半,很明显时间复杂度为O(log n)。

(n代表集合中元素的个数)三分搜索法:O(3log3n)空间复杂度:O(1)。

六、实验体会本次试验解决了二分查找和三分查找的问题,加深了对分治法的理解,收获很大,同时我也理解到学习算法是一个渐进的过程,算法可能一开始不是很好理解,但是只要多看几遍,只看是不够的还要动手分析一下,这样才能学好算法。

七、附录:(源代码)二分搜索法:#include<iostream.h>#include<stdio.h>int binarySearch(int a[],int x,int n){int left=0;int right=n-1;int i,j;while(left<=right){int middle=(left+right)/2;if(x==a[middle]){i=j=middle;return 1;}if(x>a[middle])left=middle+1;else right=middle-1;}i=right;j=left;return 0;}int main(){ int a[10]={0,1,2,3,4,5,6,7,8,9};int n=10;int x=9;if(binarySearch(a,x,n))cout<<"找到"<<endl;elsecout<<"找不到"<<endl;return 0;}实验二动态规划——求解最优问题一、实验目的1.加深学生对动态规划算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;2.提高学生利用课堂所学知识解决实际问题的能力;3.提高学生综合应用所学知识解决实际问题的能力。

分治算法的实验报告

分治算法的实验报告

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

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

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

二、实验目的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. 合并排序合并排序是一种稳定的排序算法,其基本思想是将待排序序列分为两个子序列,分别对两个子序列进行排序,然后将排序后的子序列合并为一个有序序列。

分治法实验报告

分治法实验报告

一. 实验目的及实验环境实验目的:熟练掌握运用分治法解决问题。

实验环境:windows下的Ubuntu虚拟机二. 实验内容利用分治法求一个数组的最大值、最小值(要求:数组的大小和数组的长度随机产生)三.方案设计分治法解决问题就是要将原问题分解成小问题,再将小问题分解成更小的问题,以此类推,直到最终分解的问题能够一步解决即可。

代码要求最后要输出数组的最大值、最小值。

所以,在用分治法求最值的函数max_min()中,需要将设置参数int *max,int *min。

即void max_min(int a[],int m,int n,int *max,int *min)。

这样就可以直接得到最大值、最小值。

该函数使用递归来实现,而递归的终止条件是最后分得的数组中只有一个或两个元素,当分得的数组元素个数大于2时,就进行递归调用。

四.测试数据及运行结果正确的3组运行结果:出现的错误:若将代码中的随机数函数返回值的类型改变,则会出现错误结果,甚至编译不通过。

五.总结1.实验过程中遇到的问题及解决办法;实验过程中,用分治法求最大值、最小值时,如果用返回值求最大值和最小值,则需要两个函数。

这样就会导致代码冗余,不会达到代码的复用性功能。

所以要将两个功能用一个函数直接实现就可以使用参数指针的形式。

2.对设计及调试过程的心得体会。

算法设计的课内实验既要实现实验的功能,还要讲究代码中算法的精妙、简单以及它的效率。

不能同其他高级语言的课内实验一样仅仅考虑如何完成该实验的功能,这样就可以真正地体验到算法与设计这门课的意义。

平时做实验时我们可以用不同算法实现,这样不仅可以积累平常上课学到的知识,还可以为以后的算法设计能力奠定基础。

平常更多地进行思考,可以让我们在求职时更受益。

六.附录:源代码(电子版)#include<stdio.h>#include<stdlib.h>#include<time.h>void max_min(int a[],int m,int n,int *max,int *min){int middle,hmax,hmin,gmax,gmin;if(m==n){ *max=a[m];*min=a[m];}else if(m==n-1){if(a[m]>a[n]){*max=a[m];*min=a[n];}else{*max=a[n];*min=a[m];}}else{max_min(a,m,middle,&gmax,&gmin);max_min(a,middle+1,n,&hmax,&hmin);if(gmax>hmax)*max=gmax;else*max=hmax;if(gmin<hmin)*min=gmin;else*min=hmin;}}int main(){int i;int max,min;srand((unsigned)time(NULL));int n=rand()%10+1;printf("数组的个数:%d\n",n);int a[n];for(i=0;i<n;i++){a[i]=rand()%50+1;printf("%d\t",a[i]);}max_min(a,0,n-1,&max,&min);printf("最大数:%d,最小数:%d\n",max,min);retur n 0;}。

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

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

《算法设计与分析》实验报告实验一递归与分治策略应用基础学号:**************姓名:*************班级:*************日期: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、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:从以下题目中任选一题完成,要求应用递归与分治策略设计解决方案。

算法设计与分析:递归与分治法-实验报告(总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) 时间复杂度的概念:指完成算法所需的计算次数或操作次数。

分治算法实验(用分治法查找数组元素的最大值和最小值)

分治算法实验(用分治法查找数组元素的最大值和最小值)

算法分析与设计实验报告第一次实验附录:完整代码(分治法)#include<iostream>#include<time.h>#include<iomanip>using namespace std;//当数组中的元素个数小于3时,处理最大值int compmax(int A[],int start,int end){int max;if(start<end) //有两个元素{if(A[start]<=A[end])max=A[end];elsemax=A[start];}else//有一个元素max=A[start];return max;}//当数组中元素的个数小于2时,处理最小值int compmin(int A[],int start,int end){int min;if(start<end) //有两个元素{if(A[start]<=A[end])min=A[start];elsemin=A[end];}else//有一个元素min=A[start];return min;}//分治法处理整个数组,求最大值与最小值void merge(int a[],int left,int right,int &Max,int &Min) //Max,Min用来保存最大值与最小值//之所以使用&引用,是由于如果只是简单的使用变量,并不会改变Max与Min的值,使用指针也可以{int max1=0,min1=0,max2=0,min2=0;if(right-left>2) //当数组中元素个数大于等于3时,进行分治{int mid=(right+left)/2;merge(a,left,mid,max1,min1); //左半边递归调用自身,求出最大值最小值,分别保存在max1,min1中merge(a,mid+1,right,max2,min2); //右半边递归调用自身,求出最大值最小值,分别保存在max2,min2中if(max1>=max2) //子序列两两合并,求出最大值与最小值,保存在Max与Min中Max=max1;elseMax=max2;if(min1<=min2)Min=min1;elseMin=min2;}else//数组中元素个数小于3时的情况,直接赋值{Max=compmax(a,left,right);Min=compmin(a,left,right);}}void ran(int *input,int n) //随机生成数组元素函数{int i;srand(time(0));for(i=0;i<n;i++)input[i]=rand();input[i]='\0';}int a[1000000]; //定义全局变量用来存放要查找的数组int main(){int n;int i;int max;int min;cout<<"请输入要查找的序列个数:"<<endl;for(i=0;i<5;i++){cin>>n;ran(a,n);clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();merge(a,0,n-1,max,min); //调用分治法算法cout<<max<<" "<<min<<endl;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间}system("pause"); //停止运行窗口return 0;}完整代码(非递归方法)#include<iostream>#include<time.h>#include<iomanip>using namespace std;void ran(int *input,int n) //随机生成数组元素函数{int i;srand(time(0));for(i=0;i<n;i++)input[i]=rand();input[i]='\0';}int a[1000000];int main(){int max=a[0],min=a[0];int i,j,n;cout<<"请输入数据规模:"<<endl;for(j=0;j<5;j++){cin>>n;ran(a,n);clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();for(i=1;i<n;i++){if(a[i]>max)max=a[i];if(a[i]<min)min=a[i];}cout<<max<<" "<<min<<endl;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间}system("pause");return 0;}。

分治法实验总结

分治法实验总结

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

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

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

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

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

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

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

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

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

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

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

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

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

递归实验报告分析总结

递归实验报告分析总结

递归实验报告分析总结递归是一种非常重要的编程思想和技巧,对于理解和解决问题具有非常大的帮助。

通过递归,我们可以将一个问题分解成为更小的子问题,从而简化问题的复杂度和难度。

在本次实验中,我深入学习了递归的原理和应用,并实践了一些递归算法。

通过这些实验,我对递归有了更深入和全面的理解,掌握了递归的使用方法和注意事项。

在实验中,我首先学习了递归的概念和原理。

递归是一种将大问题分解成小问题的算法思想,通过不断调用自己来解决问题。

递归算法通常包含两个部分:基本情况和递归情况。

基本情况是递归终止的条件,递归情况是递归调用自身的条件。

通过合理设置这两个条件,我们可以确保递归算法能够得到正确的结果并正常终止。

然后,我练习了递归的应用。

在实验中,我实现了一些常见的递归算法,如计算阶乘、斐波那契数列等。

通过这些实践,我更加熟悉了递归的写法和思维模式。

递归算法的核心思想是将大问题分解成小问题,然后通过递归调用解决这些小问题,最终得到整个问题的解。

这种思维模式非常灵活和高效,对于解决一些复杂和抽象的问题非常有帮助。

在实验过程中,我也遇到了一些递归算法的常见问题和注意事项。

例如,递归算法容易出现堆栈溢出的问题,因为每次递归调用都会占用一定的内存空间,如果递归层数过多,就容易导致栈溢出。

为了解决这个问题,我们可以在递归算法中加入递归深度的限制条件,或者考虑使用迭代算法等其他算法思想。

此外,递归算法的时间复杂度一般比较高,因为递归算法需要不断的调用自身,导致函数的调用次数非常多。

为了提高递归算法的效率,我们可以尝试使用尾递归优化、记忆化搜索等技巧。

尾递归优化是指在递归函数的最后一步调用中,直接返回递归函数的结果,而不再进行其他操作。

这样可以有效避免函数调用的堆栈积累,提高程序的性能。

总的来说,通过本次递归实验,我对递归算法有了更深入的理解和掌握。

递归是一种非常强大和灵活的算法思想,可以用来解决各种复杂的问题。

通过合理设置递归的基本情况和递归情况,我们可以通过递归算法简化问题的复杂度和难度,高效地解决问题。

递归函数实验报告心得

递归函数实验报告心得

一、实验背景在本次实验中,我们学习了递归函数的概念、原理以及应用。

递归函数是一种在函数内部调用自身的方法,它能够解决许多复杂的问题,具有简洁、直观的特点。

通过本次实验,我对递归函数有了更深入的了解,以下是我对实验的心得体会。

二、实验内容1. 实验目的通过本次实验,掌握递归函数的定义、原理和应用,能够运用递归函数解决实际问题。

2. 实验原理递归函数是一种在函数内部调用自身的方法,其特点是函数自身作为子问题解决者。

递归函数由两部分组成:递归基准和递归步骤。

(1)递归基准:当问题规模足够小,可以直接求解时,递归基准给出了问题的直接解。

(2)递归步骤:将原问题转化为一个规模较小的子问题,然后递归调用自身来求解。

3. 实验内容本次实验主要涉及以下几个递归函数的编写和测试:(1)计算阶乘(2)打印整数各位数(3)计算斐波那契数列(4)逆序输出字符串(5)汉诺塔问题三、实验过程及心得1. 阶乘函数在编写阶乘函数时,我首先确定了递归基准,即当n=1时,阶乘为1。

然后根据递归步骤,将原问题转化为计算n-1的阶乘,并将结果乘以n。

通过不断递归调用自身,最终得到n的阶乘。

心得:在编写递归函数时,要注意递归基准和递归步骤的确定,确保函数能够正确收敛。

2. 打印整数各位数该函数通过不断取余和整除操作,将整数拆分为各个位数,并逆序打印。

心得:在编写递归函数时,要注意处理好输入参数和返回值,确保函数逻辑正确。

3. 计算斐波那契数列斐波那契数列是一个经典的递归问题,通过递归调用自身,可以得到数列的任意项。

心得:在编写递归函数时,要注意优化递归过程,避免重复计算。

4. 逆序输出字符串该函数通过递归调用自身,将字符串的第一个字符输出,然后对剩余的字符串进行递归处理。

心得:在编写递归函数时,要注意处理边界条件,确保函数能够正确执行。

5. 汉诺塔问题汉诺塔问题是一个经典的递归问题,通过递归调用自身,将n-1个盘子移动到目标位置,然后将剩余的盘子移动到目标位置。

算法与设计实验报告

算法与设计实验报告

实验一分治与递归(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的公共子序列。

分治法实验报告详细

分治法实验报告详细

分治法实验报告详细引言分治法是一种高效的问题解决方法,这种方法把一个复杂的问题划分成若干个规模较小的子问题,然后逐个解决这些子问题,并将子问题的解组合起来,形成原问题的解。

在本实验中,我们将通过实际案例来演示和验证分治法的有效性和高效性。

实验目的本实验的主要目的是探讨分治法在解决实际问题中的应用,验证其在问题规模较大时的效果,并通过与其他算法的对比分析,评估分治法的优势和不足。

实验材料与方法我们选择了一个具体的实际问题作为案例:在一个包含n个元素的列表中,查找特定元素x的位置。

为了模拟问题的规模,我们首先生成了一个包含1000个随机整数的列表,然后从中随机选择一个元素作为我们要查找的目标x。

我们采用了如下的分治法解决方案:1. 将列表分成两个子列表,分别包含前半部分和后半部分的元素。

2. 如果目标元素x等于列表的中间元素,则返回中间元素的位置。

3. 如果目标元素x小于列表的中间元素,则递归调用步骤1,查找前半部分子列表中的目标元素x。

4. 如果目标元素x大于列表的中间元素,则递归调用步骤1,查找后半部分子列表中的目标元素x。

5. 如果子列表为空,则说明目标元素x不存在于列表中。

实验结果与分析我们依次使用二分查找法和分治法来解决上述问题,并记录它们的运行时间。

重复实验10次,并计算它们的平均运行时间。

实验结果如下:- 二分查找法平均运行时间:0.002秒- 分治法平均运行时间:0.001秒通过实验数据可以看出,分治法的运行时间明显优于二分查找法。

这是因为分治法通过将问题划分为更小的子问题,使得每个子问题的规模减小,从而减少了解决每个子问题的时间。

而二分查找法则只是将问题逐步缩小,没有有效地利用子问题之间的联系。

结论通过本实验,我们验证了分治法在解决实际问题中的有效性和高效性。

与其他算法相比,分治法在处理问题规模较大时表现出更好的性能。

因此,我们可以得出结论,对于复杂问题的解决,分治法是一种值得采用的优秀方法。

递归实验报告分析总结

递归实验报告分析总结

一、实验背景递归是一种编程技巧,通过函数自身调用自身的方式实现算法的求解。

递归算法在解决一些具有递归特性的问题上具有独特的优势,如斐波那契数列、汉诺塔等。

本实验旨在通过递归算法解决实际问题,加深对递归的理解和应用。

二、实验目的1. 掌握递归算法的基本思想和方法;2. 熟悉递归算法的编写和调试;3. 分析递归算法的时间复杂度和空间复杂度;4. 学会运用递归算法解决实际问题。

三、实验内容1. 斐波那契数列求解2. 汉诺塔问题3. 递归求解组合问题四、实验过程1. 斐波那契数列求解(1)问题描述:给定一个正整数n,求斐波那契数列的第n项。

(2)递归算法实现:```pythondef fibonacci(n):if n <= 1:return nelse:return fibonacci(n-1) + fibonacci(n-2)```(3)分析:斐波那契数列递归算法的时间复杂度为O(2^n),空间复杂度为O(n)。

2. 汉诺塔问题(1)问题描述:有n个大小不同的盘子,初始放置在A柱子上,按照从小到大的顺序排列。

现要求将所有盘子移动到C柱子上,在移动过程中,每次只能移动一个盘子,且在移动过程中,大盘子不能放在小盘子上面。

(2)递归算法实现:```pythondef hanoi(n, source, target, auxiliary):if n == 1:print("Move disk 1 from", source, "to", target)returnhanoi(n-1, source, auxiliary, target)print("Move disk", n, "from", source, "to", target)hanoi(n-1, auxiliary, target, source)```(3)分析:汉诺塔递归算法的时间复杂度为O(2^n),空间复杂度为O(n)。

递归实验报告

递归实验报告

递归实验报告篇一:字符串,递归实验报告宁波工程学院电信学院计算机教研室实验报告一、实验目的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. 通过本次实验,我们对递归算法的基本概念和原理有了更深入的理解。

算法设计与分析实验报告

算法设计与分析实验报告

本科实验报告课程名称:算法设计与分析实验项目:递归与分治算法实验地点:计算机系实验楼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.递归式,就是如何将原问题划分成子问题。

分治法实验报告范文

分治法实验报告范文

分治法实验报告范文分治法(Divide and Conquer)是一种计算机算法设计方法,它通过将问题分解成更小的子问题,然后逐个解决这些子问题,最后将结果合并起来得到最终解。

本实验旨在通过实际问题应用分治法,探究其效果和应用场景。

一、实验目的和原理实验目的:了解分治法的基本原理和实现方式,比较分治法与其他算法的效率和适用性实验原理:分治法将一个问题划分成更小的子问题,递归地解决这些子问题,然后将结果合并起来得到最终解。

二、实验步骤和结果1.实验步骤:(1)选择合适的实际问题,将其转化为具体的算法问题。

(2)实现分治法算法,并编写程序。

(3)测试算法的效果,比较其与其他算法的性能和效率。

2.实验结果:以寻找数组中最大数为例,来展示分治法的应用。

```#include <iostream>using namespace std;//定义找最大数的函数int findMax(int arr[], int left, int right)if (left == right)return arr[left];} elseint mid = (left + right) / 2;int maxLeft = findMax(arr, left, mid);int maxRight = findMax(arr, mid + 1, right);if (maxLeft > maxRight)return maxLeft;} elsereturn maxRight;}}int maiint arr[] = {15, 18, 29, 43, 2, 5, 11};int n = sizeof(arr) / sizeof(arr[0]);int maxNum = findMax(arr, 0, n - 1);cout << "The maximum number is: " << maxNum << endl;return 0;```实验结果如下:The maximum number is: 43三、实验讨论和总结1. 实验讨论:通过实验可以看出,分治法能够较快地找到数组中的最大数,时间复杂度为O(logn),效率较高。

分治法实验报告范文

分治法实验报告范文

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

要求:设计十进制的大整数乘法,必须利用分治的思想编写算法,利用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循环语句
四、实验总结
在本次实验中,我知道了分治算法,以及分治算法的基本思想。

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

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

递归与分治实验报告班级:计科1102 姓名:赵春晓学号:2011310200631实验目的:进一步掌握递归与分治算法的设计思想,通过实际问题来应用递归与分治设计算法。

实际问题:1集合划分问题,2输油管道问题,3邮局选址问题,4整数因子分解问题,5众数问题。

问题1:集合划分算法思想:对于n个元素的集合,可以划分为由m个子集构成的集合,例如{{1,2}{3,4}}就是由2个子集构成的非空子集。

假设f(n,m)表示将n个元素划分成由m个子集构成的集合的个数。

那么1)若m == 1 ,则f(n,m)= 1 ;2)若n == m ,则f(n,m)= 1 ;3)若不是上面两种情况则有下面两种情况构成:3.1)向n-1个元素划分成的m个集合里面添加一个新的元素,则有m*f(n-1,m)种方法;3.2)向n-1个元素划分成的m-1个集合里添加一个由一个元素形成的独立的集合,则有f(n-1,m-1)种方法。

实验代码:#include<iostream>#include<fstream>using namespace std ;int jihehuafen( int n , int m ){if( m == 1 || n == m )return 1 ;elsereturn jihehuafen( n - 1 , m - 1 ) + m*jihehuafen( n - 1 , m ) ;}int main(){ifstream fin("C:/input.txt") ;ofstream fout("C:/output.txt") ;int N , M , num ;fin >> N >> M ;num = jihehuafen( N , M) ;fout << num << endl ;return 0 ;}问题2:输油管道算法思想:由于主管道由东向西铺设。

故主管道的铺设位置只和各油井的y坐标有关。

要使主管道的y坐标最小,主管道的位置y坐标应是各个油井y坐标的中位数。

先用快速排序法把各个油井的y坐标排序,然后取其中位数再计算各个油井y坐标与中位数差值的绝对值之和。

实验代码:#include<iostream>#include<fstream>#include<cmath>using namespace std ;struct point//定义坐标结构体{int x ;int y ;};//快速排序void sort( point a[] , int size ){int i = 0 , j = size - 1 ;int temp ;//用来保存作为基准的数if( size >= 1 ){temp = a[0].y ;//用区间的第一个元素作为基准while( i != j )//区间两端交替向中间扫描,知道i = j{while( i < j && a[j].y > temp )j-- ; //从右向左扫描,找到第一个小于temp的a[j] if( i < j )//表示找到a[j] ,把a[j] 赋给a[i]{a[i].y = a[j].y ;i++ ;}while( i < j && a[i].y < temp )i++ ;//从左向右扫描,找到第一个大于temp 的a[i] if( i < j )//表示找到a[i],把a[i]赋给a[j]{a[j].y = a[i].y ;j-- ;}}a[i].y = temp ;sort( a , i ) ;//对左递归sort( a + i + 1 , size - i - 1 ) ;//对右递归}}//取中位数int madian( point *a , int size ){int num = size + 1 ;return a[num/2 - 1].y ;//return size%2 ? a[size>>1].y :( a[size>>1].y + a[ (size>>1) +1 ].y)>>1 ; }//计算最短路程int lucheng( point *a , int size ){int mid = madian( a , size ) ;int i , sum = 0 ;for( i = 0 ; i < size ; i ++ ){sum +=abs( a[i].y - mid ) ;}return sum ;}int main(){ifstream fin( "C:/input.txt") ;ofstream fout( "C:/output.txt") ;int n ;fin >> n ;point *p = new point[n] ;for( int i = 0 ; i < n ; i ++)fin >> p[i].x >> p[i].y ;sort( p , n ) ;int minlen = lucheng( p , n) ;fout << minlen << endl ;return 0 ;}问题3:邮局选址问题算法思想:同问题2实验代码:#include<iostream>#include<fstream>#include<cmath>using namespace std ;struct point{int x ;int y ;} ;void sort_x( point *a , int size ){int temp ;int i = 0 , j = size - 1 ;if( size >= 1 ){temp = a[0].x ;//while( i != j ){while( i < j && a[j].x > temp )j-- ;if( i < j ){a[i].x = a[j].x ;i++ ;}while( i < j && a[i].x < temp )i++ ;if( i < j ){a[j].x = a[i].x ;j-- ;}}a[i].x = temp;sort_x( a , i ) ;//sort_x( a + i +1 , size - i - 1 ) ;// }}void sort_y( point *a , int size ){int temp ;int i = 0 , j = size - 1 ;if( size >= 1 ){temp = a[0].y ;//while( i < j ){while( i < j && a[j].y > temp )j-- ;if( i < j ){a[i].y = a[j].y ;i++ ;}while( i < j && a[i].y < temp )i++ ;if( i < j ){a[j].y = a[i].y ;j-- ;}}a[i].y = temp;sort_y( a , i ) ;//sort_y( a + i +1 , size - i - 1 ) ;//}}int madian_x( point *a , int size ){//int num = size + 1 ;//return a[num/2 - 1].x ;return size%2 ? a[size>>1].x :( a[size>>1].x + a[ (size>>1) +1 ].x)>>1 ; }int madian_y( point *a , int size ){int num = size + 1 ;return a[num/2 - 1].y ;//return size%2 ? a[size>>1].y :( a[size>>1].y + a[ (size>>1) +1 ].y)>>1 ; }int lucheng( point *a , int size ){int mid_x = madian_x( a , size ) ;int mid_y = madian_y( a , size ) ;int i , sum = 0 ;for( i = 0 ; i < size ; i ++ ){sum += abs( a[i].y - mid_y ) + abs(a[i].x - mid_x ) ;}return sum ;}int main(){ifstream fin("C:/input.txt") ;ofstream fout("C:/output.txt") ;if( !fin ){cout<<"the file can't open!"<<endl;return - 1 ;}int n ;fin >> n ;point *p = new point[n] ;for( int i = 0 ; i < n ; i++ ){fin >> p[i].x >> p[i].y ;}sort_x( p , n ) ;sort_y( p , n ) ;int minlen = lucheng( p , n ) ;fout << minlen << endl ;delete []p ;return 0 ;}问题4:整数因子分解问题算法思想:采用递归的算法思想实验代码:#include<iostream>#include<fstream>using namespace std ;int count = 0 ;void yinzifenjie( int x )if( x == 1 ){count++;}else{for( int i = 2 ; i <= x ; i++ ){if( x % i == 0 ){yinzifenjie(x/i);}}}}int main(){ifstream fin("C:/input.txt") ;ofstream fout("C:/output.txt") ;if( !fin ){cout<<"the file can't open!"<<endl;return - 1 ;}int x ;fin >> x ;yinzifenjie(x) ;fout << count << endl ;return 0 ;}问题5:众数问题算法思想:首先利用快速排序将其数组排序,利用写的求中位数函数及其返回中位数起始点函数编写求众数。

相关文档
最新文档