实验报告 分治与递归
递归与分治算法心得

递归与分治算法心得
递归与分治算法都是常用的算法思想,可以很好地解决复杂问题。
递归算法是通过将问题分解为相同或相似的子问题来解决整个问题,然后再逐步合并回原问题的过程。
递归算法通常需要明确边界条件,以确保递归能够正确地停止。
分治算法是将问题分解成若干个相同或相似的子问题,递归地解决这些子问题,然后合并这些子问题的解来解决原始问题。
通常,分治算法可以高效地解决问题,但需要注意分解问题的方式和合并子问题的解的过程。
在实际应用中,递归和分治算法可以相互结合,以解决更加复杂的问题。
例如,可以使用分治算法来将问题分解成多个子问题,然后使用递归算法来解决这些子问题。
此外,还可以在递归算法中使用分治算法来对子问题进行分解和合并。
总而言之,递归与分治算法都是非常有用的算法思想,可以在许多领域中得到应用。
但是,在实际使用时,需要仔细考虑问题的性质和算法的复杂度,以确保算法的正确性和效率。
- 1 -。
递归与分治算法心得

递归与分治算法心得
递归与分治算法是算法设计中常见的两种方法,它们在解决问题时都采用了“分而治之”的思想,将问题分解成更小的子问题,然后通过递归调用或者合并子问题的解来得到原问题的解。
通过我的学习和实践,我深刻认识到了递归与分治算法的重要性和优势。
首先,递归算法可以使问题的描述更加简单明了。
通过将问题转化为自身的子问题,我们可以建立起更为简洁优美的数学模型。
其次,递归算法可以使问题的解决过程更加自然。
在递归过程中,我们可以利用已知的子问题解决同类问题,实现代码的复用和模块化。
此外,递归算法还可以解决一些重要的数学问题,如斐波那契数列和二分查找等。
分治算法则更加注重问题的分解和合并。
它将问题划分成若干个规模相同或相近的子问题,然后将子问题的解合并起来得到原问题的解。
这种方法在解决某些复杂问题时具有很大的优势。
例如,在排序算法中,归并排序采用了分治算法的思想,将待排序的序列分成两个长度相等的子序列,然后递归地对子序列排序,最后将子序列合并成有序序列。
这种算法具有较高的稳定性和灵活性,常常被应用于海量数据的排序任务中。
总之,递归与分治算法是算法设计中不可或缺的两种方法。
在解决问题时,我们应该根据具体情况选择合适的算法,并在实践中不断探索、总结和优化。
只有这样,我们才能更好地应对日益复杂多变的计算机科学挑战。
递归和分治法

递归和分治法摘要:1.递归和分治法的定义2.递归和分治法的区别3.递归和分治法的应用实例4.递归和分治法的优缺点正文:递归和分治法是计算机科学中常用的两种算法设计技巧。
它们在解决问题时都采用了将问题分解成更小子问题的思路,但在具体实现上却有所不同。
下面,我们来详细了解一下递归和分治法。
1.递归和分治法的定义递归法是指在算法中调用自身来解决问题的方法。
递归函数在执行过程中,会将原问题分解成规模更小的相似子问题,然后通过调用自身的方式,解决这些子问题,最后将子问题的解合并,得到原问题的解。
分治法是指将一个大问题分解成若干个规模较小的相似子问题,然后分别解决这些子问题,最后将子问题的解合并,得到原问题的解。
分治法在解决问题时,通常需要设计一个主函数(master function)和一个子函数(subfunction)。
主函数负责将问题分解,子函数负责解决子问题。
2.递归和分治法的区别递归法和分治法在解决问题时都采用了将问题分解成更小子问题的思路,但它们在实现上存在以下区别:(1)函数调用方式不同:递归法是通过调用自身来解决问题,而分治法是通过调用不同的子函数来解决问题。
(2)递归法必须有递归出口,即必须有一个基线条件,而分治法不一定需要。
3.递归和分治法的应用实例递归法应用广泛,例如斐波那契数列、汉诺塔问题、八皇后问题等。
分治法也有很多实际应用,例如快速排序、归并排序、大整数乘法等。
4.递归和分治法的优缺点递归法的优点是代码简单易懂,但缺点是容易产生大量的重复计算,导致时间复杂度较高。
分治法的优点是时间复杂度较低,但缺点是代码实现相对复杂,需要设计主函数和子函数。
总之,递归和分治法都是解决问题的有效方法,具体应用需要根据问题的特点来选择。
算法实验报告

实验一分治与递归算法的应用一、实验目的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. 合并排序合并排序是一种稳定的排序算法,其基本思想是将待排序序列分为两个子序列,分别对两个子序列进行排序,然后将排序后的子序列合并为一个有序序列。
《算法设计与分析》实验报告实验一...

《算法设计与分析》实验报告实验一递归与分治策略应用基础学号:**************姓名:*************班级:*************日期: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页)实验目的:掌握递归与分治法的基本思想和应用,学会设计和实现递归算法和分治算法,能够分析和评价算法的时间复杂度和空间复杂度。
实验内容: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) 时间复杂度的概念:指完成算法所需的计算次数或操作次数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int first = low; int last = high; int m=rand()%high; int key = a[m]; a[m]=a[first]; a[first]=key; while(first < last) {
if(mid==a[mid]) { i=mid;
return true; } if(mid<a[mid]) {
right=mid-1; else {
left=mid+1; } } if(a[left]==left) { i=left; return true; } return false; }五、运行结果 1、
cout <<a[i-1]<< " "; if (i%10==0)
cout<<endl; } cout<<endl; int k; cout<<"查找第 k 小的数,请输入 k:"; cin>>k; select(a, 0, n-1,k); cout<<"第"<<k<<"小的数字为"<<a[k-1]<<endl; delete[] a; system("pause");
bool BinarySearch(int a[],int n,int &i);
int main() { int a[]={-1,0,1,3,8,10,32,56,67,78,89};
int n,i; n=sizeof(a)/4; cout<<"数组 a 为:"; for(int m=0;m<n;m++) cout<<a[m]<<" "; if(BinarySearch(a,n,i))
实验报告 分治与递归
中国矿业大学 计算机科学与技术学院 孟靖宇
基本题一:基本递归算法
一、实验目的与要求 1、熟悉 C/C++语言的集成开发环境; 2、通过本实验加深对递归过程的理解
二、实验内容:
掌握递归算法的概念和基本思想,分析并掌握“整数划分”问题的递归算法。 三、实验题
任意输入一个整数,输出结果能够用递归方法实现整数的划分。 四、算法思想
直接选择排序:得到最小的数,需要 (n 1) 次比较;得到第二小的数,需要 (n 2) 次
3n2 3 比较;得到第 k 小的数,需要 (n k) 次比较因此,总比较次数为 8 ,其时间
复杂性为 O(n2 ) 。
四、代码实现 #include "stdafx.h" #include <iostream> #include <cstdlib> #include <stdlib.h> using namespace std;
int main() {
while(1) { int n; cout<<"生成包含 n 个元素的数组,请输入 n:"; cin>>n; cout<<endl; int *a=new int[n]; for(int i=0;i<n;i++) {
a[i]=rand()%1000; } for(int i=1;i<=n;i++) {
int left=0; int right=n-1; while(left<right) {
int mid=(left+right)/2; if(x==a[mid]) {
i=j=mid; return true; } if(x>a[mid]) { left=mid+1; } else {
right=mid-1; } } if(a[left]==x) { i=j=left; return true; } if(x<a[left]) { i=left-1; j=left; } else { i=left; j=left+1; } return false; } 2、 #include "stdafx.h" #include <iostream> #include <stdlib.h> using namespace std;
int n; cout<<"请输入要划分的整数:"<<endl; cin>>n; int p=q(n,n); cout<<"正整数"<<n<<"有"<<p<<"种不同的划分"<<endl; system("pause");
return 0; } int q(int n,int m){
if((n<1)||(m<1)) return 0; if((n==1)||(m==1)) return 1; if(n<m) return q(n,n); if(n==m) return q(n,m-1)+1; return q(n,m-1)+q(n-m,m); } 六、运行结果
int main() {
int a[]={1,2,4,6,8,10,32,56,67,78,89}; int n,i,j,x; n=sizeof(a)/4; cout<<"数组 a 为:"; for(int m=0;m<n;m++) {
cout<<a[m]<<" "; } while(1) { cout<<endl<<"输入需要查找的数:"; cin>>x; if(BinarySearch(a,n,x,i,j)) {
对于数据 n,递归计算最大加数等于 x 的划分个数+最大加数不大于 x-1 的划分个数。最 大加数 x 从 n 开始,逐步变小为 n-1,…,1。
考虑增加一个自变量:对于数据 n,最大加数 n1 不大于 m 的划分个数记作 q(n, m) 。则
有:
1
n 1, m 1
q (n,
m)
q(n, n) 1 q(n, n 1)
2、
六、实验小结 通过本次试验: 1、熟悉了二分搜索算法; 2、初步掌握了分治算法;
提高题一: 用分治法实现元素选择
一、实验要求与目的 1、了解分治法的基本思想,掌握递归程序编写方法;
2、使用分治法编程,求解线形序列中第 k 小元素。 二、实验内容
1、给定线形序列集中 n 个元素和一个整数 k,1≤k≤n,输出这 n 个元素中第 k 小元素 的值及其位置。 2、简述该算法的原理、步骤。对该算法与直接排序查找进行比较。 3、编写并调试程序。 4、测试要求:元素个数不少于 100;分三种情况:k=1、k=n 和 k=中位数。 三、算法思想 随机产生支点 J,对输入数组进行划分为 a 和 b 两段,然后计算 a 部分的元素个数 j: 如果 k<=j,则第 k 小元素落在 a 段,为 a 段的第 k 小元素; 如果 k>j,则 a 段的所有元素都比第 k 小元素还要小,第 k 小元素落在 b 段,为 b 段中 的第 k-j 小元素(-j 的含义是去掉 a 段的元素总个数)
六、实验小结 通过本次试验: 1、 熟悉了 C/C++语言的集成开发环境;
2、通过本实验加深了对递归过程的理解
基本题二:二分搜索
一、实验目的与要求 1、熟悉二分搜索算法; 2、初步掌握分治算法;
二、实验题 1、设 a[0:n-1]是一个已排好序的数组。请改写二分搜索算法,使得当搜索元素 x 不在数 组中时,返回小于 x 的最大元素的位置 I 和大于 x 的最小元素位置 j。当搜索元素在数 组中时,I 和 j 相同,均为 x 在数组中的位置。 2、设有 n 个不同的整数排好序后存放于 t[0:n-1]中,若存在一个下标 i,0≤i<n,使得
1、 #include "stdafx.h" #include <iostream> #include <stdlib.h> #include<windows.h>
using namespace std; bool BinarySearch(int a[],int n,int x,int &i,int &j);
cout<<"能找到,该数下标为"<<i<<endl; } else {
cout<<"找不到,小于该数的最大数的下标为"<<i<<",大于该数的最小数的下 标为"<<j<<endl;
} system("pause"); } return 0; }
bool BinarySearch(int a[],int n,int x,int &i,int &j) {
cout<<endl<<"能找到值等于下标的数组元素,该元素为:"<<i<<endl; else
cout<<"找不到"; system("pause"); return 0; }
bool BinarySearch(int a[],int n,int &i) {
int left=0; int right=n-1; while(left<right) { int mid=(left+right)/2;